How to write a Dockerfile for a Python app
October 29, 2026 · 2 min read
Write a Dockerfile that starts from a Python base image, installs your packages from requirements.txt, copies your code, and sets the command that starts the app. Then docker build and docker run do the rest.
A small Flask app in a container
Make a folder with three files. First, app.py:
from flask import Flask
app = Flask(__name__)
PRICES = {
"House Espresso, 5 lb": 55,
"Single Origin, 5 lb": 72,
}
@app.route("/")
def price_list():
text = "Kettle & Crane wholesale prices\n"
for name, price in PRICES.items():
text += f"{name}: ${price}\n"
return text, {"Content-Type": "text/plain"}
Second, requirements.txt, with exact versions:
flask==3.1.3
gunicorn==26.2.0
Third, the Dockerfile:
FROM python:3.15-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
Build and run it:
docker build -t pricelist .
docker run -d --name pricelist -p 8000:8000 pricelist
curl -s http://localhost:8000
Output of the curl command:
Kettle & Crane wholesale prices
House Espresso, 5 lb: $55
Single Origin, 5 lb: $72
What each line does
FROMpicks the base image.-slimis a smaller Python image.WORKDIR /appcreates/appand makes it the working folder.COPY requirements.txt .andRUN pip install ...come before the code on purpose. Docker reuses a finished step if nothing before it changed, so editingapp.pydoes not reinstall your packages.COPY . .copies the rest of your folder, includingapp.py.EXPOSE 8000is documentation. You still need-p 8000:8000to reach the port.CMDis the command the container runs. Gunicorn is a production web server; Flask's built-in one is only for testing.
Common mistake
Binding to 127.0.0.1. A server listening on localhost inside a container only accepts connections from that container, so curl fails with Empty reply from server or Connection reset by peer. Bind to 0.0.0.0, as the CMD above does.
Running the build in the wrong folder. "/requirements.txt": not found means the file is not in the build context, the . at the end of docker build. Run the command in the folder that holds your files.
Remove the container with docker rm -f pricelist when you are done.
A Python Dockerfile is six lines: base image, working folder, install requirements, copy code, expose the port, run the server on 0.0.0.0.