The Flask development server is not meant for production use and only intended for local development. It is not secure, stable, efficient, or scaled for a production environment. In addition to choosing a production server, this ADR will specify a high level implementation option.
Decision Drivers
Scalable: The chosen solution should be configurable to scale and a multi-worker, multi-threaded production-ready, WSGI wrapper.
Ease of use: The production server should be relatively simple to set up and start.
Well-maintained: We have a preference towards a production server that is widely adopted and have active maintainers.
Options Considered
Production Server
Gunicorn
Waitress
Implementation
API entrypoint responsible for conditional logic determining dev vs prod environment and starting corresponding server
Dockerfile executable command for the prod server is overridden in the IaC task definition, API by default starts dev server
Dockerfile executable command for the dev server is overridden in docker-compose.yml, API by default starts prod server
Note: Gunicorn can be set up either using their unique configuration file or in our code using separate app entry points for dev and prod. We want to make sure we are scaling the appropriate number of workers based on CPU.
Decision Outcome
Production Server
Chosen option: Gunicorn, because it is the industry standard, well-supported and documented.
Implementation
Chosen option: #3 Dockerfile executable command for the dev server is overridden in docker-compose.yml, API by default starts prod server. This is because it makes the most sense in our current development ecosystem and abstracts away the concept of environment in the API layer.