docker-fastapi
Comprehensive Docker containerization for Python/FastAPI applications from development to production deployments. Use when Claude needs to containerize Python/FastAPI applications with proper multi-stage builds, production-ready configurations, security best practices, and optimized Docker images for deployment to cloud platforms or container orchestration systems.
Best use case
docker-fastapi is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Comprehensive Docker containerization for Python/FastAPI applications from development to production deployments. Use when Claude needs to containerize Python/FastAPI applications with proper multi-stage builds, production-ready configurations, security best practices, and optimized Docker images for deployment to cloud platforms or container orchestration systems.
Teams using docker-fastapi should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/docker-fastapi/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How docker-fastapi Compares
| Feature / Agent | docker-fastapi | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Comprehensive Docker containerization for Python/FastAPI applications from development to production deployments. Use when Claude needs to containerize Python/FastAPI applications with proper multi-stage builds, production-ready configurations, security best practices, and optimized Docker images for deployment to cloud platforms or container orchestration systems.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Docker FastAPI
## Overview
This skill provides comprehensive guidance for containerizing Python/FastAPI applications using Docker. It includes best practices for Dockerfile creation, multi-stage builds, production configurations, security hardening, and deployment strategies from development to production environments.
## Decision Hierarchy
When optimizing containers, resolve conflicts in this order:
1. **Security** (non-negotiable): Non-root user (UID 10001+), no secrets in image, health checks
2. **Runtime Size** (beats build speed): Multi-stage builds even if slower to build
3. **Operational Clarity** (beats cleverness): Explicit over implicit, predictable behavior
4. **Build Speed** (when above are satisfied): UV package manager, layer caching
## Core Capabilities
### 1. Dockerfile Generation
- **Development Dockerfiles**: Fast feedback loops with hot-reloading
- **Production Dockerfiles**: Optimized, secure, minimal images using multi-stage builds
- **Security-focused**: Non-root users (UID 10001+), minimal base images, no shell access
- **Performance-optimized**: Layer caching, UV official images, dependency optimization
- **Best Practice Compliant**: Proper instruction ordering, comprehensive comments, .dockerignore generation
### 2. Multi-stage Build Patterns (P1: Always Use Multi-Stage)
- **Builder Stage**: Has compilers, dev tools, UV package manager
- **Runtime Stage**: Minimal production image, no build tools, no UV
- **Layer Optimization**: Efficient caching and reduced image sizes
### 3. Production Deployment Patterns
- **Process Management**: Proper process managers (gunicorn, uvicorn) for FastAPI
- **Resource Management**: Memory and CPU constraints
- **Health Checks**: Native Python health checks (no curl dependency)
- **Environment Configuration**: Proper environment variable handling
### 4. Build Principles
**P1: Multi-Stage Always** - Even if current deps don't require compilation, future deps might.
**P2: Layer Order Matters** - Copy dependency files first, install, then copy source:
```dockerfile
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-cache
COPY src/ ./src/
```
**P3: Single RUN for Related Operations** - Combine related commands to reduce layers:
```dockerfile
RUN groupadd -g 10001 appgroup && \
useradd -u 10001 -g appgroup -s /sbin/nologin appuser && \
chown -R appuser:appgroup /app
```
## Quick Start Guide
### Production Multi-stage Build (Recommended)
For production deployments with optimized security and size:
```dockerfile
# syntax=docker/dockerfile:1
# ============================================
# BUILD STAGE - Has UV, compilers, dev tools
# ============================================
FROM ghcr.io/astral-sh/uv:python3.12-slim AS builder
WORKDIR /app
# P2: Dependency files first (changes less frequently)
COPY pyproject.toml uv.lock ./
# P3: Install deps into virtual env, not system Python
RUN uv sync --frozen --no-cache --no-dev
# P2: Source code last (changes most frequently)
COPY src/ ./src/
COPY main.py ./
# ============================================
# RUNTIME STAGE - Minimal, no build tools
# ============================================
FROM python:3.12-slim AS runtime
WORKDIR /app
# Runtime environment
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PATH="/app/.venv/bin:$PATH"
# P3: User setup in single layer with secure defaults
# UID 10001+ for Kubernetes pod security compliance
RUN groupadd -g 10001 appgroup && \
useradd -u 10001 -g appgroup -s /sbin/nologin appuser && \
mkdir -p /app && \
chown -R appuser:appgroup /app
# P1: Copy only runtime artifacts from builder (no UV, no build tools)
COPY --from=builder --chown=appuser:appgroup /app/.venv /app/.venv
COPY --from=builder --chown=appuser:appgroup /app/src /app/src
COPY --from=builder --chown=appuser:appgroup /app/main.py /app/
# Switch to non-root user (use numeric UID for portability)
USER 10001
EXPOSE 8000
# Health check using Python (no curl needed - smaller attack surface)
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
# Production command
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```
### With Gunicorn Workers (High Traffic)
```dockerfile
# syntax=docker/dockerfile:1
# ============================================
# BUILD STAGE
# ============================================
FROM ghcr.io/astral-sh/uv:python3.12-slim AS builder
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-cache --no-dev
COPY src/ ./src/
COPY main.py ./
# ============================================
# RUNTIME STAGE
# ============================================
FROM python:3.12-slim AS runtime
WORKDIR /app
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PATH="/app/.venv/bin:$PATH" \
WORKERS=4 \
TIMEOUT=120 \
KEEP_ALIVE=5 \
MAX_REQUESTS=1000 \
MAX_REQUESTS_JITTER=100
RUN groupadd -g 10001 appgroup && \
useradd -u 10001 -g appgroup -s /sbin/nologin appuser && \
mkdir -p /app && \
chown -R appuser:appgroup /app
COPY --from=builder --chown=appuser:appgroup /app/.venv /app/.venv
COPY --from=builder --chown=appuser:appgroup /app/src /app/src
COPY --from=builder --chown=appuser:appgroup /app/main.py /app/
USER 10001
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
CMD ["sh", "-c", "gunicorn main:app --workers ${WORKERS} --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --timeout ${TIMEOUT} --keep-alive ${KEEP_ALIVE} --max-requests ${MAX_REQUESTS} --max-requests-jitter ${MAX_REQUESTS_JITTER}"]
```
### Alpine Variant (Smallest Size)
```dockerfile
# syntax=docker/dockerfile:1
# ============================================
# BUILD STAGE
# ============================================
FROM ghcr.io/astral-sh/uv:python3.12-alpine AS builder
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-cache --no-dev
COPY src/ ./src/
COPY main.py ./
# ============================================
# RUNTIME STAGE
# ============================================
FROM python:3.12-alpine AS runtime
WORKDIR /app
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PATH="/app/.venv/bin:$PATH"
# Alpine uses addgroup/adduser with different flags
RUN addgroup -g 10001 appgroup && \
adduser -D -u 10001 -G appgroup -s /sbin/nologin appuser && \
mkdir -p /app && \
chown -R appuser:appgroup /app
COPY --from=builder --chown=appuser:appgroup /app/.venv /app/.venv
COPY --from=builder --chown=appuser:appgroup /app/src /app/src
COPY --from=builder --chown=appuser:appgroup /app/main.py /app/
USER 10001
EXPOSE 8000
# Alpine has wget built-in (no curl needed)
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget --spider -q http://localhost:8000/health || exit 1
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```
### Development Dockerfile (Hot-reloading)
For development with automatic reloading (security relaxed for convenience):
```dockerfile
FROM python:3.12-slim
WORKDIR /app
# Install UV for fast dependency installation
RUN pip install --no-cache-dir uv
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-cache
COPY . .
ENV PATH="/app/.venv/bin:$PATH"
EXPOSE 8000
# Development command with auto-reload
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
```
### Legacy: requirements.txt Support
If not using pyproject.toml/uv.lock:
```dockerfile
# syntax=docker/dockerfile:1
FROM ghcr.io/astral-sh/uv:python3.12-slim AS builder
WORKDIR /app
COPY requirements.txt ./
RUN uv venv && uv pip install --no-cache -r requirements.txt
COPY src/ ./src/
COPY main.py ./
FROM python:3.12-slim AS runtime
WORKDIR /app
ENV PYTHONUNBUFFERED=1 \
PATH="/app/.venv/bin:$PATH"
RUN groupadd -g 10001 appgroup && \
useradd -u 10001 -g appgroup -s /sbin/nologin appuser && \
mkdir -p /app && \
chown -R appuser:appgroup /app
COPY --from=builder --chown=appuser:appgroup /app/.venv /app/.venv
COPY --from=builder --chown=appuser:appgroup /app/src /app/src
COPY --from=builder --chown=appuser:appgroup /app/main.py /app/
USER 10001
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```
## Production Deployment Patterns
### Docker Compose for Development
For local development with database and other services:
```yaml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "8000:8000"
volumes:
- .:/app
- /app/.venv # Don't mount venv from host
environment:
- DATABASE_URL=postgresql://user:password@db:5432/mydb
depends_on:
db:
condition: service_healthy
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 5s
timeout: 5s
retries: 5
volumes:
postgres_data:
```
### Docker Compose for Production
```yaml
version: '3.8'
services:
app:
image: myapp:latest
ports:
- "8000:8000"
environment:
- DATABASE_URL=${DATABASE_URL}
- API_KEY=${API_KEY}
- WORKERS=4
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
cpus: '0.25'
restart: unless-stopped
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
```
## Security Best Practices
### 1. Non-root User Execution (UID 10001+)
Always run containers as a non-root user with high UID for K8s compliance:
```dockerfile
# Debian/Ubuntu
RUN groupadd -g 10001 appgroup && \
useradd -u 10001 -g appgroup -s /sbin/nologin appuser && \
chown -R appuser:appgroup /app
USER 10001
# Alpine
RUN addgroup -g 10001 appgroup && \
adduser -D -u 10001 -G appgroup -s /sbin/nologin appuser && \
chown -R appuser:appgroup /app
USER 10001
```
**Why UID 10001+?**
- Kubernetes `runAsNonRoot` and `MustRunAsNonRoot` policies
- Avoids collision with host system users
- Better security audit compliance
### 2. Health Checks Without Curl
Don't install curl just for health checks - use native tools:
```dockerfile
# Python (recommended - no extra dependencies)
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
# Alpine (wget is built-in)
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget --spider -q http://localhost:8000/health || exit 1
```
### 3. Secret Management
Never hardcode secrets - pass them at runtime:
```dockerfile
# ❌ NEVER do this
ENV DATABASE_URL=postgresql://user:password@host/db
ENV API_KEY=sk_live_abc123
# ✅ Do this - empty defaults, inject at runtime
ENV DATABASE_URL="" \
API_KEY=""
```
```bash
# Pass secrets at runtime
docker run -e DATABASE_URL=$DATABASE_URL -e API_KEY=$API_KEY myapp:latest
# Or use Docker secrets (Swarm) / Kubernetes secrets
```
### 4. Minimal Attack Surface
- Use multi-stage builds (no build tools in production)
- Don't install curl, wget, or other tools unless necessary
- Use `/sbin/nologin` as shell to prevent interactive access
- Use distroless or Alpine for smallest possible image
## Build Optimization
### Layer Caching Strategy
Order matters for cache efficiency:
```dockerfile
# 1. Base image (rarely changes)
FROM python:3.12-slim
# 2. System deps (changes occasionally)
RUN apt-get update && apt-get install -y ...
# 3. Python deps (changes when pyproject.toml changes)
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-cache
# 4. Application code (changes frequently)
COPY src/ ./src/
```
### Image Size Comparison
| Approach | Typical Size |
|----------|-------------|
| `python:3.12` (full) | ~900MB |
| `python:3.12-slim` | ~150MB |
| `python:3.12-alpine` | ~50MB |
| Multi-stage slim | ~100-200MB |
| Multi-stage alpine | ~50-100MB |
## Common Commands
### Build and Run
```bash
# Build with BuildKit (recommended)
DOCKER_BUILDKIT=1 docker build -t my-fastapi-app .
# Build with metadata
docker build \
--build-arg BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
--build-arg VERSION=1.0.0 \
-t my-fastapi-app:1.0.0 .
# Run the container
docker run -p 8000:8000 my-fastapi-app
# Run with environment variables
docker run -p 8000:8000 -e WORKERS=8 my-fastapi-app
```
### Validation Tests
```bash
# Test 1: Verify non-root user
docker run --rm my-fastapi-app whoami
# Expected: appuser (not root)
# Test 2: Verify UID
docker run --rm my-fastapi-app id
# Expected: uid=10001(appuser) gid=10001(appgroup)
# Test 3: Verify health check works
docker run -d --name test my-fastapi-app
sleep 10
docker inspect test | jq '.[0].State.Health.Status'
# Expected: "healthy"
docker rm -f test
# Test 4: Check image size
docker images my-fastapi-app
```
## Kubernetes Deployment
For K8s, `HEALTHCHECK` is ignored - use pod probes:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-app
spec:
replicas: 3
selector:
matchLabels:
app: fastapi-app
template:
metadata:
labels:
app: fastapi-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
containers:
- name: app
image: my-fastapi-app:latest
ports:
- containerPort: 8000
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 2
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
```
## Troubleshooting
### 1. Application Not Starting
- Check logs: `docker logs <container>`
- Verify correct module path in CMD
- Ensure all dependencies installed in venv
### 2. Permission Issues
- Check file ownership: `docker run --rm myapp ls -la /app`
- Ensure directories created before USER directive
- Use `--chown` with COPY commands
### 3. Health Check Failing
- Test endpoint manually: `docker exec <container> python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"`
- Increase `--start-period` for slow-starting apps
- Check application logs for errors
### 4. Large Image Size
- Use multi-stage builds
- Use Alpine base images
- Remove `__pycache__` and `.pyc` files
- Check for unnecessary dependencies
## References
This skill includes the following resources:
- **scripts/**: Docker build and deployment helper scripts
- **references/**: Detailed Docker and FastAPI deployment guides
- **assets/**: Dockerfile templates for different scenariosRelated Skills
featbit-deployment-docker
Expert guidance for deploying FeatBit with Docker Compose across three tiers - Standalone (PostgreSQL only), Standard (PostgreSQL/MongoDB + Redis), and Professional (+ ClickHouse + Kafka). Use when user mentions "docker-compose", "deploy with Docker", "standalone vs standard vs pro", works with docker-compose.yml files, or asks about container configuration, environment variables, or production Docker setup.
FastAPI Kubernetes Deployment
This skill should be used when the user asks to "deploy FastAPI to Kubernetes", "create Dockerfile", "build Docker image", "write Helm chart", "configure K8s deployment", "add health checks", "scale FastAPI", or mentions Docker, Kubernetes, K8s, containers, Helm, or deployment. Provides containerization and orchestration patterns.
dockerfile-optimization
Optimize Dockerfiles for smaller images, faster builds, better caching, and security. Use this skill when writing, reviewing, or debugging Dockerfiles.
Docker Hub Automation
Automate Docker Hub tasks via Rube MCP (Composio): repositories, images, tags, and container registry management. Always search tools first for current schemas.
docker
Docker y Compose. Proyecto usa este skill; contenido canónico en .ai-system.
docker-workflow
Comprehensive Docker containerization workflow covering multi-stage builds, docker-compose orchestration, image optimization, debugging, and production best practices. Use when containerizing applications, setting up development environments, or deploying with Docker.
docker-vigil-orchestration
Docker Compose orchestration for Vigil Guard v2.0.0 microservices (11 services). Use when deploying services, managing containers, troubleshooting Docker network issues, working with vigil-net, configuring docker-compose.yml, handling service dependencies, or working with 3-branch detection services (heuristics, semantic, prompt-guard).
docker-to-k8s-manifests
Automatically generate optimized Kubernetes deployment manifests from Dockerfile and docker-compose configurations with proper resource limits and health checks.
docker-test-environments
Docker-based test environment management for isolated, reproducible test execution. Create Docker Compose environments, manage test containers, configure service dependencies, and integrate with CI/CD pipelines.
docker-setup
Dockerfile and Docker Compose patterns with multi-stage builds, layer optimization, security hardening, and health checks. Use when containerizing applications, writing Dockerfiles, or setting up Docker Compose environments.
docker-optimize
Audit and optimize Dockerfiles and docker-compose files for size, security, build speed, and best practices. Triggers on: optimize dockerfile, audit docker, fix dockerfile, docker best practices, docker compose security.
docker-node
Containerization for TypeScript/Node.js applications. Use when deploying Node.js backends, need consistent dev environments, or setting up CI/CD pipelines. Covers multi-stage builds, docker-compose for development, and production optimization. Choose this skill for containerizing tRPC/Express APIs with Prisma.