Docker changed how we deploy applications. No more "it works on my machine" problems. Here's everything a Python developer needs to know to get started with Docker.
Why Docker?
Before Docker:
- "Works on my machine"
- Complex environment setup
- Dependency conflicts
- Hard to scale
With Docker:
- Consistent environments everywhere
- One command setup
- Isolated dependencies
- Easy horizontal scaling
Your First Dockerfile
# Dockerfile
FROM python:3.11-slim
# Set working directory
WORKDIR /app
# Copy requirements first (for layer caching)
COPY requirements.txt .
# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Expose port
EXPOSE 8000
# Run the application
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Sample FastAPI App
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello from Docker!"}
@app.get("/health")
def health_check():
return {"status": "healthy"}
# requirements.txt
fastapi==0.104.1
uvicorn==0.24.0
Build and Run
# Build the image
docker build -t my-python-app .
# Run the container
docker run -p 8000:8000 my-python-app
# Run in background (detached)
docker run -d -p 8000:8000 my-python-app
# View running containers
docker ps
# Stop a container
docker stop <container_id>
Docker Compose for Multi-Service Apps
# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:password@db:5432/mydb
depends_on:
- db
volumes:
- .:/app
db:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
# Start all services
docker-compose up
# Start in background
docker-compose up -d
# Stop all services
docker-compose down
Essential Docker Commands
# Images
docker images # List images
docker pull python:3.11-slim # Pull image
docker rmi my-image # Remove image
# Containers
docker ps -a # List all containers
docker logs <container_id> # View logs
docker exec -it <id> /bin/bash # Shell into container
docker rm <container_id> # Remove container
# Cleanup
docker system prune # Remove unused resources
Environment Variables
import os
# In your Python app
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///default.db")
API_KEY = os.getenv("API_KEY", "")
DEBUG = os.getenv("DEBUG", "False").lower() == "true"
# Pass env vars when running
docker run -e API_KEY=your_key -e DEBUG=true my-app
# Use .env file
docker run --env-file .env my-app
Production Best Practices
# Multi-stage build for smaller images
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Free Hosting Options
- Railway.app: Deploy Docker containers free
- Render.com: Free tier for containerized apps
- Fly.io: Generous free tier
- Google Cloud Run: Pay only when running
Need Help Containerizing Your App?
Already have a Python application but struggling with deployment?
- REST API Development - Deploy-ready APIs from $20
- AI Chatbot Development - Containerized AI chatbots from $20
What Python apps are you containerizing with Docker? Share below!
Top comments (0)