Write a Dockerfile for a custom Docker image
Create a custom Docker image by writing a Dockerfile with essential instructions for containerizing applications.
Fresh bytes every Thursday. No spam, ever. Unsubscribe anytime.
Join 9,000+ developers and get three free video lessons every week.
A Dockerfile is just a text file that contains instructions for building a Docker image. Think of it as a recipe that tells Docker exactly how to create your application environment.
Let's look at a practical example of serving a simple Python web application, and break down what’s going on with this list of instructions:
- Lines starting with # are comments. Docker will ignore these lines when it builds your image.
- The first line
FROM python:3.13.1
specifies our base image. You can find official Docker images at https://hub.docker.com, which is the official public repository of Docker images. We can then find Python's official Docker image and see all of the versions available for this image. The3.13.1
after the colon specifies which version of the image that we want to use as the base for our custom image. You’ll also notice that there are many other variations of this tag available, such as3
,latest
, and3.13.1-bookworm
. I’d recommend using the most specific version possible, as using versions such as3
orlatest
can introduce updates which can break your app. This is why I picked3.13.1
for this Docker image. RUN
executes any shell command. Here, we're installing the Flask package using pip, but this could be any command you'd normally type in your terminal.ENV
sets environment variables that will be available to our application. Flask apps typically run on port 5000 in development, but we're using 8000 here, as it's a common port to run Python apps on within production.WORKDIR
sets up where our application will live in the image./app
is a common convention to use for your app code in containers.COPY
takes two arguments: a source (where the file is on your computer), and a destination (where you want it in the container). The.
means "current directory", soCOPY app.py .
copiesapp.py
into our working directory (/app
).CMD
defines what command runs when the container starts. We use the square brackets format (called "exec form")["python", "app.py"]
instead ofpython app.py
because this is what runs our Python process directly as PID (process ID) 1, without wrapping it in a seperate shell. This ensures our app can handle shutdown signals properly, and makes the container run more efficiently.
For this to run, we’ll also need an app.py
file present next to our Dockerfile. Here is an example of a Flask application which we can use when it comes time to building our image:
Quick note: Running this script withÂ
host='0.0.0.0'
 tells Flask to listen on all network interfaces, not just localhost. This is an important concept to use for Docker-based apps, because otherwise our app wouldn't be accessible from outside the container.
The Dockerfile contains everything that is needed to properly containerize a Python app. Each instruction builds on the previous one, which results in creating a complete environment which can run our app.