skills/docker/SKILL.md
Use when editing Dockerfile, Containerfile-like Docker syntax, docker-compose.yml, docker-compose.yaml, .dockerignore, multi-stage builds, BuildKit cache mounts, Compose services, or image optimization.
npx skillsauth add cofin/flow dockerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Docker provides OS-level virtualization via containers. This skill covers Dockerfile best practices, multi-stage builds, distroless images, Compose orchestration, and BuildKit optimizations.
Multi-stage builds separate build-time dependencies from the runtime image, producing minimal production images.
# ---- Stage 1: dependency builder ----
FROM python:3.12-slim-bookworm AS builder
WORKDIR /app
RUN pip install --no-cache-dir uv
COPY pyproject.toml uv.lock ./
# Cache uv's package download cache across builds
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev --no-editable
# ---- Stage 2: runtime (distroless, non-root) ----
FROM gcr.io/distroless/python3-debian12:nonroot
WORKDIR /app
COPY --from=builder /app/.venv/lib/python3.12/site-packages /usr/lib/python3.12/site-packages
COPY src/ ./src/
ENTRYPOINT ["python", "-m", "myapp"]
Key rules:
AS builder, AS runner, etc.).COPY --from=.# compose.yml
services:
app:
build: .
image: myapp:dev
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://app:secret@db:5432/mydb
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: mydb
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d mydb"]
interval: 10s
timeout: 5s
retries: 5
volumes:
pg_data:
# Common Compose commands
docker compose up -d # start detached
docker compose logs -f app # follow service logs
docker compose exec app bash # shell into running container
docker compose down -v # stop and remove volumes
docker compose build --no-cache # full rebuild
--mount=type=cache persists a directory between builds so package managers do not re-download.
# uv (Python)
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
# pip
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
# apt
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y --no-install-recommends curl
# npm
RUN --mount=type=cache,target=/root/.npm \
npm ci --omit=dev
# Go modules
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
Enable BuildKit (default in Docker 23+):
export DOCKER_BUILDKIT=1
docker build .
# or
docker buildx build .
uv is a fast Python package/project manager. Use it as the build-stage installer, then copy the resulting .venv into the runtime stage.
FROM python:3.12-slim-bookworm AS builder
WORKDIR /app
RUN pip install --no-cache-dir uv
COPY pyproject.toml uv.lock ./
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev --no-editable
| Image | Use case |
|-------|----------|
| gcr.io/distroless/static-debian12:nonroot | Statically compiled binaries (Go, Rust) |
| gcr.io/distroless/base-debian12:nonroot | Dynamically linked, needs glibc |
| gcr.io/distroless/python3-debian12:nonroot | Python applications |
| gcr.io/distroless/nodejs22-debian12:nonroot | Node.js applications |
Always use the :nonroot tag — the image user is UID 65532.
tini properly forwards signals and reaps zombie processes. Use it when the base image does not include an init system (e.g., non-distroless slim images).
FROM python:3.12-slim-bookworm
RUN apt-get update \
&& apt-get install -y --no-install-recommends tini \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["tini", "--"]
CMD ["python", "-m", "myapp"]
Distroless images already run as non-root; for non-distroless images add tini + explicit non-root user.
UID 65532 is the nonroot user in distroless images. Align custom user IDs with this value for consistency.
# For non-distroless images
RUN groupadd --gid 65532 nonroot \
&& useradd --uid 65532 --gid 65532 --no-create-home --shell /bin/false nonroot
USER nonroot
.git
.github
.venv
__pycache__
*.pyc
*.pyo
node_modules
.env
.env.*
Dockerfile
docker-compose*.yml
compose*.yml
.dockerignore
coverage
.pytest_cache
.mypy_cache
.ruff_cache
dist
build
*.md
!README.md
<workflow>
.git, .env, node_modules, __pycache__.docker buildx build -t myimage:dev .docker image inspect myimage:dev for size; dive myimage:dev for layer breakdown.docker run --rm myimage:dev id should print uid=65532.compose.yml with health checks and depends_on conditions.:nonroot distroless tags or add an explicit non-root user (UID 65532). Never run as root in production..env, secrets, .git, and large directories into the build context.python:3.12-slim-bookworm, not python:latest) to ensure reproducible builds.COPY .env or RUN echo SECRET=.... Use --secret mount or runtime injection.Before delivering Dockerfile or Compose config, verify:
:latest).dockerignore is present and excludes secrets/cachesFor detailed guides and code examples, refer to the following documents in references/:
# Build stage
FROM python:3.12-slim-bookworm AS builder
WORKDIR /app
RUN pip install --no-cache-dir uv
COPY pyproject.toml uv.lock ./
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev --no-editable
# Runtime stage
FROM gcr.io/distroless/python3-debian12:nonroot
WORKDIR /app
COPY --from=builder /app/.venv/lib/python3.12/site-packages /usr/lib/python3.12/site-packages
COPY src/ ./src/
ENTRYPOINT ["python", "-m", "myapp"]
</example>
development
Use when tracing execution paths, mapping dependencies, understanding unfamiliar code, following data flow, investigating end-to-end behavior, debugging call chains, or deciding which files to read next.
development
Use when reviewing authentication, authorization, user input, secrets, API keys, database queries, file uploads, session management, external API calls, OWASP risks, or data handling attack surface.
testing
Use when analyzing tradeoffs, comparing approaches, weighing options, assessing risks, stress-testing conclusions, identifying blind spots, or applying multiple viewpoints to a decision.
development
Use when reviewing hot paths, slow code, database queries, N+1 risks, memory usage, loops, I/O, caching strategy, concurrency, latency-sensitive paths, or resource efficiency.