Included in this repo is information to dockerize Flask with Postgres, Gunicorn, and Nginx. A comprehensive tutorial can be found here.
Using a modified Instagram tech stack, dockerizing Flask allows us to get a fully working web service. This was done by creating necessary files for a simple web app. To do this, Flask was configured to run on Docker with Postgres. Nginx and Gunicorn were added for production environments and serving static and user-uploaded media files (via Nginx). The web service follows a microservices architecture, with Docker containers encapsulating different components. Requests flow through Nginx, which acts as a reverse proxy, forwarding requests to Gunicorn for processing Flask application logic. This setup enables users to test a production environment locally and ensures effective handling of static and media files. We can see an example of locally uploading and viewing a user-uploaded media file here:
Dependencies:
- Flask v2.3.2
- Docker v23.0.5
- Python v3.11.3
Please Note: Docker and Docker Compose must be installed. Instructions to set this up can be found here. This project utilized rootless docker.
(Uses Postgres)
-
Build the images and spin up containers:
$ docker-compose up -d --build
-
Navigate to test it at http://localhost:7447. You should see:
{ "hello": "world" }
-
Spin down development containers (and associated volumes with
-v
flag.)$ docker compose down -v
*(Uses gunicorn & nginx) (make sure to spin down development containers before proceeding)
- Build the production images and spin up containers:
$ docker-compose -f docker-compose.prod.yml up -d --build
- Navigate to test it at http://localhost:7447. You should see:
{ "hello": "world" }
- Spin down development containers (and associated volumes with
-v
flag.)$ docker-compose -f docker-compose.prod.yml down -v
(make sure to spin down development containers before proceeding)
-
Build new image and spin up containers:
$ docker-compose up -d --build
-
Create the table:
$ docker-compose exec web python manage.py create_db
-
Ensure table creation:
$ docker-compose exec db psql --username=hello_flask --dbname=hello_flask_dev
Keys Information:
# \l
: List of databases# \c hello_flask_dev
: connects to database "hello_flask_dev" as user "hello_flask"# \dt
: List of relations# q
: exit/quit -
Navigate to test at http://localhost:7447
-
Bring down development containers
$ docker-compose down -v
- Re-build images and spin up containers:
$ docker-compose up -d --build
- Ensure http://localhost:7447/static/hello.txt serves up the file correctly
- Spin down development containers:
$ docker-compose down -v
- Re-build images and spin up containers:
$ docker-compose -f docker-compose.prod.yml up -d --build
- Navigate to ensure static asset loaded correctly: http://localhost:7447/static/hello.txt
- Spin down containers:
$ docker-compose -f docker-compose.prod.yml down -v
- Re-build images and spin up containers:
$ docker-compose up -d --build
- Navigate to http://localhost:7447/upload.
- Upload an image
- View the image at http://localhost:7447/media/IMAGE_FILE_NAME
- Spin down development containers:
docker-compose down -v
- Re-build:
$ docker-compose -f docker-compose.prod.yml up -d --build $ docker-compose -f docker-compose.prod.yml exec web python manage.py create_db
- Test:
- Upload an image at http://localhost:7447/upload
- View image at http://localhost:7447/media/IMAGE_FILE_NAME