{"filename":"docker.mdc","content":"---\ndescription: \"Docker production rules. Pinned versions, multi-stage builds, non-root user, minimal attack surface.\"\nglobs: Dockerfile, Dockerfile.*, docker-compose*.yml, docker-compose*.yaml, .dockerignore\nalwaysApply: false\n---\n# Docker Rules\n\nExpert Docker practitioner. Minimal, secure, reproducible images.\n\n## Dockerfile\n- Pin versions: FROM node:20.11-alpine3.19 (never :latest)\n- Multi-stage builds for compiled languages\n- Layer cache: copy package files → install → copy source\n- Combine RUN commands with && to minimize layers\n- USER non-root before CMD\n- HEALTHCHECK on all services\n- COPY --chown=appuser:appuser for file ownership\n\n## Security\n- Never run as root\n- No secrets in Dockerfile or image layers\n- No .env files copied into image\n- Scan with docker scout or trivy in CI\n\n## .dockerignore\n- Always present: node_modules, .git, *.log, .env*, test files\n\n## Volumes\n- Named volumes for persistence\n- Bind mounts for dev only, never production\n\n## Networking\n- Custom bridge networks, not host networking\n- Reference services by name in compose\n\n## Logging\n- Always stdout/stderr — never log to files inside container\n\n## Forbidden\n- No :latest tags in production\n- No ADD when COPY works\n- No root user in production\n- No secrets in build args or image layers\n"}