Why & How to Containerize Your Existing Python Apps
Containerize your Python apps to eliminate environment issues and simplify deployment. This guide shows you why it helps and how to get started with Docker.

Image by Author | Ideogram
If you've been wondering how to make your Python apps more portable, consistent, and deployment-ready, you're in the right place. Containerization isn't just a buzzword. It's a practical skill that'll immediately level up your development workflow.
In this guide, I'll walk you through containerizing a simple FastAPI application step by step. No fluff, just practical knowledge you can apply to your own projects today. Ready to dive in?
Why Containerize Your Python Applications?
Before we dive into the how, let's talk about the why:
- Consistency across environments: "It works on my machine" becomes a thing of the past. When you use containers, you have the guarantee that your app runs the same way everywhere.
- Isolation: Each container has its own dependencies, avoiding conflicts with other applications or system libraries.
- Portability: Ship your application anywhere Docker runs - from your laptop to AWS, Azure, or any cloud provider.
- Scalability: Containers are lightweight and start quickly, making them perfect for scaling services up or down as needed.
- DevOps friendly: Containers fit perfectly into modern CI/CD pipelines, making continuous deployment smoother.
Now that you understand the benefits, let's containerize a real Python application! We'll use Docker, the go-to choice for containerization.
▶️ Before you begin: Install Python and Docker to code along.
How to Containerize a Python FastAPI Application
We'll build and containerize a simple FastAPI app that converts between currencies. This example walks you through key concepts you can apply to your own projects.
Let’s first create a project directory:
$ mkdir currency-api
$ cd currency-api
Next, create and activate a virtual environment:
$ python3 -m venv venv
$ source venv/bin/activate # On Windows: venv\Scripts\activate
Then install the necessary packages:
$ pip3 install fastapi uvicorn
Create a main.py file with the following code:
from fastapi import FastAPI, HTTPException, Query
from pydantic import BaseModel
from typing import Literal
app = FastAPI(title="Currency Converter")
class ConversionResponse(BaseModel):
from_currency: str
to_currency: str
amount: float
converted: float
rate: float
mock_rates = {
("USD", "EUR"): 0.91,
("EUR", "USD"): 1.10,
("USD", "JPY"): 145.0,
}
@app.get("/convert", response_model=ConversionResponse)
def convert(
amount: float = Query(..., gt=0),
from_currency: Literal["USD", "EUR"] = "USD",
to_currency: Literal["USD", "EUR", "JPY"] = "EUR",
):
if from_currency == to_currency:
raise HTTPException(
status_code=400, detail="From and to currencies must differ."
)
rate = mock_rates.get((from_currency, to_currency))
if not rate:
raise HTTPException(status_code=400, detail="Conversion rate not available.")
converted = amount * rate
return ConversionResponse(
from_currency=from_currency,
to_currency=to_currency,
amount=amount,
converted=round(converted, 2),
rate=rate,
)
This creates an API endpoint /convert that takes an amount, source currency, and target currency, validates them. It then uses mock exchange rates to convert the amount and returns the result in a structured JSON format.
Step 2: Create a requirements.txt File
Next, create a requirements.txt file:
fastapi==0.115.12
uvicorn==0.34.2
This file pins specific versions of our dependencies to ensure our container builds consistently.
Step 3: Create a Dockerfile
Now for the main event: creating our Dockerfile. This is the key step in the containerization process.
Here’s the Dockerfile:
# Use official Python image
FROM python:3.11-slim
# Set work directory
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy app code
COPY . .
# Expose port
EXPOSE 8000
# Run the app
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Let's break down what this Dockerfile does:
- Base image: We start with
python:3.11-slim, a lightweight Python image that's perfect for production. - Setting the working directory:
WORKDIR /appcreates and sets the working directory inside the container. - Dependency installation: We install all the requirements. This leverages Docker's layer caching, so changing your app code doesn't trigger a full dependency reinstall.
- Copying application code:
COPY . .copies our code into the container. - Port exposure:
EXPOSE 8000tells Docker which port the application uses. - Startup command: Finally, we use Uvicorn to run our FastAPI app with the proper configuration for container environments.
Step 4: Create a .dockerignore File
You can add a .dockerignore file to keep your container lean.
This file is like .gitignore for your projects. It prevents unnecessary files from being copied into the container environment.
This keeps the container size small and avoids potential issues with local development files.
Here’s an example .dockerignore file.
Step 5: Build and Run Your Container
Now let's build and run our containerized application:
# Build the Docker image
$ docker build -t currency-api .
# Run the container
$ docker run -p 8000:8000 currency-api
These commands:
- Build a Docker image named
currency-apifrom the current directory (note the dot at the end) - Run a container from this image, mapping port 8000 on your host to port 8000 in the container
Your FastAPI app is now running in a container! You can now access the app at http://localhost:8000.
Step 6: Test the Containerized API
Test your API endpoints. Let's use cURL to send a conversion request to our API's /convert endpoint like so:
$ curl "http://localhost:8000/convert?amount=100&from_currency=USD&to_currency=EUR"
Output:
{
"from_currency": "USD",
"to_currency": "EUR",
"amount": 100.0,
"converted": 91.0,
"rate": 0.91,
}
Wrapping Up
And there you have it! Your Python FastAPI application is now containerized and ready for prime time. This approach works for virtually any Python application, not just FastAPI. The same principles apply whether you're containerizing Flask, Django, or any other Python framework.
The actual value of containerization comes when you start deploying to different environments. Now you can confidently push your containerized app to development, staging, or production environments knowing it will behave consistently everywhere.
What's next? Consider exploring Docker Compose for multi-container applications, container orchestration with Kubernetes, or CI/CD pipelines to build on your new containerization skills.
Happy containerizing!
Bala Priya C is a developer and technical writer from India. She likes working at the intersection of math, programming, data science, and content creation. Her areas of interest and expertise include DevOps, data science, and natural language processing. She enjoys reading, writing, coding, and coffee! Currently, she's working on learning and sharing her knowledge with the developer community by authoring tutorials, how-to guides, opinion pieces, and more. Bala also creates engaging resource overviews and coding tutorials.