AgentSkillsCN

docker-production-deployment

涵盖 Dockerfile 的最佳实践(多阶段构建、单阶段构建、非 root 用户)、环境变量与密钥管理、卷挂载、requirements.txt 固定版本、.dockerignore 以及适用于 Python 应用的 CI/CD 模式。在容器化 Python 应用、准备生产镜像或搭建构建/部署流水线时使用。

SKILL.md
--- frontmatter
name: docker-production-deployment
description: Covers Dockerfile best practices (multi-stage, single-stage, non-root user), environment variables and secrets, volume mounting, requirements.txt pinning, .dockerignore, and CI/CD patterns for Python applications. Use when containerizing Python apps, preparing production images, or setting up build/deploy pipelines.

Docker & Production Deployment Expert

When to Apply

  • Writing or reviewing Dockerfiles for Python apps
  • Managing env vars and secrets in containers
  • Defining dependencies (requirements.txt) or build context (.dockerignore)
  • Setting up CI/CD for Docker builds and tests

Dockerfile Best Practices

Single-Stage (Typical Python App)

  • Base: FROM --platform=linux/arm64 python:3.11-slim (or match target platform).
  • WORKDIR /app.
  • Install system deps only if needed (gcc, g++ for compiled packages); clean apt cache.
  • COPY requirements.txt . then pip install --no-cache-dir -r requirements.txt.
  • Copy app (src/, main.py, data/), create output dirs.
  • Set ENV PYTHONUNBUFFERED=1, ENV PYTHONPATH=/app.
  • Run as non-root: create user, chown, USER appuser.
  • CMD ["python", "main.py"].
  • Optional: HEALTHCHECK with a simple probe.

Multi-Stage (When Build Deps Differ from Runtime)

  • Builder stage: install build deps and Python packages into /root/.local (or venv).
  • Runtime stage: same slim base; COPY --from=builder /root/.local /root/.local; set PATH; copy app only. Reduces image size and separates build/runtime.

Secrets and Environment

  • Do not hardcode API keys or secrets in Dockerfile or image.
  • Use empty placeholders in Dockerfile if needed: ENV GEMINI_API_KEY="".
  • Pass at run time: docker run --env-file .env ... or -e VAR=value. Add .env to .gitignore and .dockerignore so it never goes into the image.

Volume Mounting (Development)

  • Mount data read-only: -v $(pwd)/data:/app/data:ro.
  • Mount outputs read-write: -v $(pwd)/outputs:/app/outputs:rw.

Requirements.txt

  • Pin versions: numpy==1.24.3, pandas==2.0.3, etc.
  • Group logically: core (numpy, pandas, matplotlib, seaborn), LLM APIs, config (python-dotenv, pydantic), logging, optional (statsmodels), dev (pytest, mypy).

.dockerignore

Exclude to keep build context small and avoid copying secrets or caches:

  • Python: __pycache__/, *.py[cod], *.so, venv/, env/, *.egg-info/, dist/, build/
  • IDE: .vscode/, .idea/
  • Env: .env, .env.local, *.key
  • Git: .git/, .gitignore
  • Docs/tests: README.md, docs/, tests/, *.pytest_cache/
  • Outputs: outputs/ (generated in container)

Docker Commands Reference

bash
# Build
docker build --platform linux/arm64 -t llm-forecaster .

# Run
docker run --rm --env-file .env llm-forecaster

# Run with volumes (dev)
docker run --rm --env-file .env \
  -v $(pwd)/data:/app/data:ro \
  -v $(pwd)/outputs:/app/outputs:rw \
  llm-forecaster

# Debug
docker run --rm -it --env-file .env llm-forecaster /bin/bash
docker logs <container_id>

CI/CD Pattern (e.g. GitHub Actions)

  • On push/PR to main: checkout, set up Docker Buildx, build image (e.g. --platform linux/arm64), tag with ${{ github.sha }}.
  • Run tests inside container: docker run -e GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }} llm-forecaster:${{ github.sha }} python -m pytest tests/.
  • Store API keys in repository secrets; never in workflow file or image.

Checklist

  • No secrets in Dockerfile or committed files
  • Non-root user in container
  • PYTHONUNBUFFERED and PYTHONPATH set
  • requirements.txt versions pinned
  • .dockerignore excludes venv, cache, .env, outputs
  • Build platform matches deployment (e.g. linux/arm64)
  • CI runs tests in built image with secrets from vault/secrets

Additional Resources

  • For Dockerfile snippets, .dockerignore list, run commands, and CI snippet, see reference.md.