Skip to content

Commit

Permalink
Run flask using production wsgi/http server (#185)
Browse files Browse the repository at this point in the history
  • Loading branch information
daphnegold committed Aug 11, 2023
1 parent 75df51b commit 5297c13
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 49 deletions.
8 changes: 6 additions & 2 deletions app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ CMD ["poetry", "run", "python", "-m", "src"]

FROM base AS release
ARG RUN_USER
WORKDIR /app

# Gunicorn requires this workaround to create writable temporary directory in
# our readonly root file system. https://github.com/aws/containers-roadmap/issues/736
RUN mkdir -p /tmp
VOLUME ["/tmp"]

# TODO(https://github.com/navapbc/template-application-flask/issues/23) Productionize the Docker image

Expand Down Expand Up @@ -105,4 +109,4 @@ ENV HOST=0.0.0.0
USER ${RUN_USER}

# Run the application.
CMD ["poetry", "run", "python", "-m", "src"]
CMD ["poetry", "run", "gunicorn", "src.app:create_app()"]
25 changes: 25 additions & 0 deletions app/gunicorn.conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
Configuration file for the Gunicorn server used to run the application in production environments.
Attributes:
bind(str): The socket to bind. Formatted as '0.0.0.0:$PORT'.
workers(int): The number of worker processes for handling requests.
threads(int): The number of threads per worker for handling requests.
For more information, see https://docs.gunicorn.org/en/stable/configure.html
"""

import os

from src.app_config import AppConfig

app_config = AppConfig()

bind = app_config.host + ':' + str(app_config.port)
# Calculates the number of usable cores and doubles it. Recommended number of workers per core is two.
# https://docs.gunicorn.org/en/latest/design.html#how-many-workers
# We use 'os.sched_getaffinity(pid)' not 'os.cpu_count()' because it returns only allowable CPUs.
# os.sched_getaffinity(pid): Return the set of CPUs the process with PID pid is restricted to.
# os.cpu_count(): Return the number of CPUs in the system.
workers = len(os.sched_getaffinity(0)) * 2
threads = 4
22 changes: 21 additions & 1 deletion app/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pytz = "^2022.2.1"
APIFlask = "^1.1.3"
marshmallow-dataclass = {extras = ["enum", "union"], version = "^8.5.8"}
marshmallow = "^3.18.0"
gunicorn = "^21.2.0"

[tool.poetry.group.dev.dependencies]
black = "^22.6.0"
Expand All @@ -42,7 +43,6 @@ requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
app-start = "src.__main__:main"
db-migrate = "src.db.migrations.run:up"
db-migrate-down = "src.db.migrations.run:down"
db-migrate-down-all = "src.db.migrations.run:downall"
Expand Down
42 changes: 0 additions & 42 deletions app/src/__main__.py

This file was deleted.

2 changes: 0 additions & 2 deletions app/src/app_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@


class AppConfig(PydanticBaseEnvConfig):
environment: str = "prod"

# Set HOST to 127.0.0.1 by default to avoid other machines on the network
# from accessing the application. This is especially important if you are
# running the application locally on a public network. This needs to be
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ services:
args:
- RUN_UID=${RUN_UID:-4000}
- RUN_USER=${RUN_USER:-app}
command: ["poetry", "run", "flask", "--app", "src.app", "run", "--host", "0.0.0.0", "--port", "8080", "--reload"]
container_name: main-app
env_file: ./app/local.env
ports:
Expand Down
2 changes: 1 addition & 1 deletion docs/app/database/database-access-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This document describes the best practices and patterns for how the application

## Client Initialization and Configuration

The database client is initialized when the application starts (see [src/\_\_main\_\_.py](../../../app/src/__main__.py). As the database engine that is used to create acquire connections to the database is initialized using the database configuration defined in [db_config.py](../../../app/src/db/db_config.py), which is configured through environment variables. The initialized database client is then stored on the Flask app's [\`extensions\` dictionary](https://flask.palletsprojects.com/en/2.2.x/src/#flask.Flask.extensions) to be used throughout the lifetime of the application.
The database client is initialized when the application starts (see [src/\_\_main\_\_.py](../../../app/src/app.py). The database engine that is used to create acquire connections to the database is initialized using the database configuration defined in [db_config.py](../../../app/src/db/db_config.py), which is configured through environment variables. The initialized database client is then stored on the Flask app's [\`extensions\` dictionary](https://flask.palletsprojects.com/en/2.2.x/src/#flask.Flask.extensions) to be used throughout the lifetime of the application.

## Session Management

Expand Down

0 comments on commit 5297c13

Please sign in to comment.