How to run a python app with docker compose

How to run a python app with docker compose
This post goes through the steps required to run a python flask app with docker compose and covers the following...
Installing docker.
Installing docker compose.
Configuring components required to run the app.
Running the python app on docker compose.
Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.
Compose works in all environments: production, staging, development, testing, as well as CI workflows
Steps
1. Installing Docker
The first thing you need to do is install docker. I am working on an Ubuntu system and you can find instructions on how to install docker in Ubuntu here.
Once you have docker installed you can continue with the following steps.
2. Installing docker compose
Now we need to install docker compose, to do so run the following command to download compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Now we need to apply executable permissions to the binary to allow us to run compose
sudo chmod +x /usr/local/bin/docker-compose
Check the install by running the following command docker-compose --version
If you get a response similar to the one in the screenshot then you are good to go.
3.Configure app components
We are going to build a python app that uses Flask and Redis. We will use Redis to keep a hit counter for our application. The Python and Redis software will be provided by docker.
I have created a repository on github for this project and cloned it to my workstation
If you don’t want to do that then create a directory for your project and cd into it
mkdir flaskapp
cd flaskapp
Now let’s create a python file called app.py
Add the following python code to the file
In this example, redis
is the hostname of the redis container on the application’s network. We use the default port for Redis which is 6379
.
Now we need to create a requirements file for our Python app
A requirements.txt file allows you to list packages you want to install in your python environment. Add the following to your requirements.txt file.
Now we are going to create a Dockerfile for our app, the Dockerfile will be used to build our docker image. The image contains all the dependencies the Python application requires, including Python itself.
In your app directory, create a file called Dockerfile
Add the following to the Dockerfile
This tells Docker to:
Build an image starting with the Python 3.4 image.
Add the current directory . into the path /code in the image.
Set the working directory to /code.
Install the Python dependencies.
Set the default command for the container to python app.py.
Now we need to create a Docker Compose file.
In your app directory create a file called docker-compose.yml
In that file add the following code
This Compose file defines two services, web and redis.
The web service uses an image that’s built from the Dockerfile we created in the current directory and it forwards the exposed port 5000 on the container to port 5000 on the host machine. Port 5000 is the default port for Flask.
The redis service uses a public Redis image pulled from the Docker Hub registry.
4.Run your app using docker Compose
We are now ready to run our app using Docker and Docker Compose.
From you app directory run the following command
sudo docker-compose up
As compose runs your screen will fill up with the commands defined in our docker files and the following steps will be carried out
Step 1/5 : FROM python:3.4-alpine#This is docker pulling the python image we defined from the docker hub
Step 2/5 : ADD . /code#This adds the content of our app directory to a directory called code in our python container.
Step 3/5 : WORKDIR /code #This sets the working directory in your Python container to /code
Step 4/5 : RUN pip install -r requirements.txt#This installs the python packages listed in our requirements.txt file
Step 5/5 : CMD ["python", "app.py"]#This defines the commands to run within our Python container once it is up. In this case it is running our app.py file.
Now open a web browser and browse to 0.0.0.0:5000 and you should see the following
If you see this your app is up and running in a docker container.
Now click refresh, if the number increases to 2 you know your Python container and your Redis container are communicating as expected.
If you want to view your containers, open another terminal and type the following
sudo docker container ls
To view your images type
sudo docker image ls
Browse to your app directory and type
sudo docker-compose ps
This shows you what compose is currently running.
To bring down you application run
sudo docker-compose down
This removes all the containers for your app.
That’s it for this tutorial. To find out more about docker compose go to
https://docs.docker.com/compose/overview/
Leave a comment below if you found this useful.
After 25+ hours of searching the web to understand how to create a python/docker development environment in a container, I finally came across your post that made clear the part that was confusing me; you first do everything on your local filesystem and then in Step 4 the magic happens -you dockerize everything.
Only part that I am not clear on in your post is where you say; “This Compose file defines two services, web and redis.
The web service uses an image that’s built from the Dockerfile we created in the current directory…”
I don’t see a webserver or redis defined in the docker file? I see redis in the requirements.txt file. So where is the webserver coming from?
Thanks for providing clarification. I appreciate it much. I am just getting started learning python and docker.
Hi Ian,
The webserver comes from flask. Flask has a built-in development server. You should only use the development server during development. The development server is provided for convenience, but is not designed to be particularly secure, stable, or efficient.