Deploying python-flask based applications using docker-compose

Software development has a variety of requirements to run an application, both on the development environment and the production environment. Modern IT infrastructure relies on containers instead of traditional virtual machines, this is because containers provide multiple advantages over VMs, such as fast booting, networking between containers, and lightweight processing which means less hardware consumption when compared to VMs. in this article we will create a docker based development environment for RESTful flask applications using docker compose. This stack can be used either for either a production environment or a development one as you can see in the following diagram:

Docker compose diagram

As you can see, a python container is used to serve the flask app using Gunicorn, and a Mysql container is used as the database server, while an Nginx container serves the frontend files. Assuming that you already know how to manage docker files and nginx configuration files, we will start discussing the docker compose file. First, we will start by defining our python container in the docker-compose.yml file

version: "3"    services:
flask_api:
image: flask-api
build: ./
ports:
- 192.168.0.20:5000:5000
env_file:
- ./flask_api.env
environment:
DATABASE_URL: mysql_db
TZ: "Africa/Tripoli"
command: gunicorn --bind 0.0.0.0:5000 manage:flask_app
restart: always
networks:
- local_net
  • flask-api: refers to the name of the container.
  • image: the image that will be created from the docker file.
  • build: the directory of the Dockerfile.
  • ports: the binding port on the host system, in this case we specified an IP / interface.
  • env_file: if you have an environment variables file.
  • environment: environment variables here instead of using .env file.
  • command: command to run on the starting of the container.
  • restart: set restarting criteria
  • networks: set custom networks for your containers environment.
        mysql_db:
image: mysql:8.0
env_file:
- ./db.env
environment:
TZ: "Africa/Tripoli"
ports:
- 192.168.0.20:3306:3306
volumes:
- ./database:/var/lib/mysql
restart: always
networks:
- local_net
  • mysql_db: is the name of the container.
  • image: the used image to build the container.
  • env_file: refers to where the environment file is located.
        web:
image: web
build: ./nginx
volumes:
- ./html:/var/www/html/
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
environment:
TZ: "Africa/Tripoli"
ports:
- 192.168.0.20:80:80
restart: always
depends_on:
- flask_api
networks:
- local_net
  • web: is the name of the container.
  • image: the name of the image which will build and used.
  • build: the Dockerfile location.
  • volumes: mount the desired volume in this case we mounted html directory and nginx config file.
networks:
local_net:
  • networks: Define the networks that will be used by container, you can define more than one network.

The final docker-compose file will looks like this :

version: "3"services:
flask_api:
image: flask-api
build: ./
ports:
- 192.168.0.20:5000:5000
env_file:
- ./flask_api.env
environment:
DATABASE_URL: mysql_db
TZ: "Africa/Tripoli"
command: gunicorn --bind 0.0.0.0:5000 manage:flask_app
restart: always
networks:
- local_net
mysql_db:
image: mysql:8.0
env_file:
- ./db.env
environment:
TZ: "Africa/Tripoli"
ports:
- 192.168.0.20:3306:3306
volumes:
- ./database:/var/lib/mysql
restart: always
networks:
- local_net
web:
image: web
build: ./nginx
volumes:
- ./html:/var/www/html
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
environment:
TZ: "Africa/Tripoli"
ports:
- 192.168.0.20:80:80
restart: always
depends_on:
- flask_api
networks:
- local_net

Finally run the command

docker-compose up --build -d
  • The build flag is for build the the compose images
  • -d flag is used to run the containers in background

If the docker containers created successfully, you can check them using the following command:

docker ps -a
  • -a is used to show the exited containers as well

Conclusion

This flask app stack could be used for development environments and testing environments. It may also be used for production environments as well, but make sure that you change the environment variables and interfaces for your use case. This article has covered only the docker-compose configuration assuming that the reader already has an experience with docker files and nginx configurations

Doing DevOps and system administration stuff

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store