Why Use Docker?
Using Linux containers offers several advantages:- Security - Isolated environments with controlled dependencies
- Replicability - Consistent behavior across development and production
- Simplicity - Easy to deploy and scale
- Portability - Run anywhere Docker is supported
Container Concepts
What is a Container?
Containers are a lightweight way to package applications with all dependencies while keeping them isolated from other containers.- Run using the same Linux kernel as the host
- Consume minimal resources compared to virtual machines
- Have isolated processes, file systems, and networks
- Typically run a single process
Container Image vs. Container
Container Image:- Static snapshot of files, environment variables, and default commands
- Like a program file (e.g.,
pythonexecutable) - Not running, just stored
- Running instance of a container image
- Like a running process
- Exists only while a process is running
A container image is to a container what a program is to a process.
Basic Dockerfile
Here’s a production-ready Dockerfile for FastAPI:Explanation
Project Structure
Your project should look like this:Example Application
app/main.py:Building and Running
Build the Image
The
. at the end tells Docker to use the current directory as the build context.Run the Container
http://localhost/.
Test the API
- Swagger UI:
http://localhost/docs - ReDoc:
http://localhost/redoc
Behind a Reverse Proxy
If running behind a TLS termination proxy (Nginx, Traefik, etc.), add--proxy-headers:
The
--proxy-headers flag enables proper handling of X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host headers.Docker Cache Optimization
The order of instructions matters for build speed:- Dependencies are cached and reused unless
requirements.txtchanges - Code changes don’t trigger dependency reinstalls
- Saves minutes on each rebuild during development
Multi-Stage Builds
For smaller production images, use multi-stage builds:- Smaller final image (uses
slimbase) - Faster deployments
- Reduced attack surface
Single File Applications
For a single-file app without theapp directory:
Workers in Containers
Single Container (Simple Deployment)
For simple deployments, use multiple workers in one container:Multiple Containers (Kubernetes/Swarm)
For orchestrated environments, run one process per container:HTTPS in Containers
HTTPS is typically handled externally by:- Traefik - Automatic certificate management
- Nginx - With Certbot for certificates
- Cloud load balancers - Managed SSL/TLS
- Kubernetes Ingress - With cert-manager
This separation allows easy certificate renewal without touching your application containers.
Docker Compose Example
For local development and simple deployments: docker-compose.yml:Using uv for Faster Builds
For faster dependency installation, use uv:Best Practices
Use Specific Python Versions
Avoid
:latest tags. Use specific versions like python:3.12 for consistency.Use Exec Form for CMD
Always use array syntax:
CMD ["fastapi", "run", ...] for proper signal handling.Deployment Options
Once you have a Docker image, deploy it to:- Docker Compose - Single server, simple setup
- Kubernetes - Multi-server, production-grade orchestration
- Docker Swarm - Simpler alternative to Kubernetes
- Cloud Container Services - AWS ECS, Google Cloud Run, Azure Container Instances
- Platform as a Service - Render, Railway, Fly.io
Most cloud providers accept Docker images directly, making deployment straightforward.
Recap
Using Docker containers simplifies handling all deployment concepts:- ✅ HTTPS - External proxy handles certificates
- ✅ Running on Startup - Container orchestrators manage this
- ✅ Restarts - Automatic with
--restartpolicies - ✅ Replication - Multiple containers or
--workers - ✅ Memory - Set limits in orchestrator config
- ✅ Pre-Start Steps - Init containers or startup scripts