Dockerize a FastAPI App
Package a FastAPI app into a Docker image. Same image runs on your laptop, Render, AWS, anywhere.
🚀 Mini Project · 5 filesProject files
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
async def root():
return {'message': 'Hello from Docker!', 'host': 'container'}
@app.get('/health')
async def health():
return {'status': 'healthy'}
fastapi==0.104.1 uvicorn[standard]==0.24.0
# Start from a slim Python base image FROM python:3.11-slim # Working directory inside the container WORKDIR /app # Install deps first (cached layer — rebuilds only when requirements.txt changes) COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Copy the rest of the code COPY . . # Expose the port the app runs on EXPOSE 8000 # Run with uvicorn, bound to all interfaces CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
version: '3.9'
services:
api:
build: .
ports:
- '8000:8000'
volumes:
- ./app:/app/app # live-reload during dev
environment:
- ENV=development
restart: unless-stopped
# Build the image (first time, or after requirements change)
docker build -t myapi .
# Run a single container
docker run -p 8000:8000 myapi
# OR use docker-compose (recommended — handles volumes, env, restart)
docker-compose up --build
# Test it
curl http://localhost:8000/
# {"message":"Hello from Docker!","host":"container"}
# View logs
docker-compose logs -f api
# Stop
docker-compose down
How it works
Docker packages your app + dependencies + OS into a single image that runs identically everywhere. The Dockerfile is the recipe: (1) FROM python:3.11-slim — start from a minimal Python base. (2) WORKDIR /app — set the working directory. (3) COPY requirements.txt + RUN pip install — install deps FIRST so this layer is cached; rebuilding after a code change skips the slow pip install. (4) COPY . . — copy the code. (5) EXPOSE 8000 — document the port. (6) CMD [...] — the command to run when the container starts. docker-compose.yml declares the service: build from current dir, map port 8000, mount ./app as a volume for live-reload, restart on crash. The big wins: no more 'works on my machine', reproducible builds, easy rollback (just run an older image).
⚡ Open in Notebook