Concepts 🚀 Project 🧮 Labs
📚 Learn / Mini Projects / Dockerize a FastAPI App

Dockerize a FastAPI App

Package a FastAPI app into a Docker image. Same image runs on your laptop, Render, AWS, anywhere.

🚀 Mini Project · 5 files

Project files

📄 app/main.py python
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'}
📄 requirements.txt text
fastapi==0.104.1
uvicorn[standard]==0.24.0
📄 Dockerfile dockerfile
# 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"]
📄 docker-compose.yml yaml
version: '3.9'
services:
  api:
    build: .
    ports:
      - '8000:8000'
    volumes:
      - ./app:/app/app    # live-reload during dev
    environment:
      - ENV=development
    restart: unless-stopped
📄 run.sh bash
# 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
🔍 Where this is used in OpenBenchML OpenBenchML's Dockerfile + docker-compose.yml at the project root. The same image runs on Render and on the Oracle Cloud VM.