Dockerfile Standard
Mandatory structure
Section titled “Mandatory structure”Container repositories use multi-stage Dockerfiles. A typical structure has dependency/build, CI/test, and runtime stages. Only the final runtime stage is published.
FROM ghcr.io/astral-sh/uv:0.11.28 AS uv
FROM python:3.12-slim-bookworm AS dependenciesWORKDIR /appCOPY --from=uv /uv /uvx /bin/COPY pyproject.toml uv.lock ./RUN uv sync --locked --no-dev --no-install-project
FROM dependencies AS ciCOPY . .RUN uv sync --locked --all-groups \ && uv run ruff format --check . \ && uv run ruff check . \ && uv run mypy . \ && uv run pytest --cov --cov-report=xml
FROM python:3.12-slim-bookworm AS runtimeRUN useradd --create-home --uid 10001 nexaCOPY --from=dependencies /app/.venv /app/.venvCOPY --chown=nexa:nexa app /app/appENV PATH="/app/.venv/bin:$PATH"USER 10001CMD ["python", "-m", "app"]A Node runtime follows the same principle:
FROM node:24-bookworm-slim AS buildWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .RUN npm run build
FROM node:24-bookworm-slim AS runtimeWORKDIR /appENV NODE_ENV=productionCOPY package*.json ./RUN npm ci --omit=dev && npm cache clean --forceCOPY --from=build /app/dist ./distUSER nodeCMD ["node", "dist/index.js"]Mandatory rules
Section titled “Mandatory rules”- Bookworm Slim is the default approved base family.
- Multi-stage builds are required unless an exception is approved.
- The CI/test stage is never published as the product image.
- Runtime images exclude compilers, caches, tests, source-control metadata, and development dependencies.
- Containers run as a non-root user.
- Secrets and registry credentials never enter image layers.
- Health behavior and graceful termination are implemented where applicable.
- Python images use the pinned uv
0.11.28builder and a committeduv.lock; Poetry and requirements-file images are migration exceptions. - Alpine or another OS family requires an ADR or approved exception.