---
name: docker
description: Dockerfile best practices, security hardening, multi-stage builds, and image optimization
---

## Docker Code Review Rules

### Security (Critical)
- Run as non-root user (`USER` directive)
- Don't store secrets in image (use runtime injection)
- Don't use `--privileged` without justification
- Scan images for vulnerabilities
- Set `readonly` root filesystem where possible
- Review any use of build-time variables (e.g., `ARG`, `ENV`, `LABEL` values) that can be influenced by external inputs (such as `--build-arg` values or CI/CD environment variables sourced from untrusted users) to ensure they are not used in a way that enables build-time injection
- Never use HTML comments (`<!-- -->`) in Dockerfiles

### Base Images
- Pin base image to specific version (not `latest`)
- Use official images from trusted sources
- Prefer minimal images (`alpine`, `slim`, `distroless`)
- Regularly update base images for security patches

### Build Optimization
- Use multi-stage builds to reduce final image size
- Order instructions by change frequency (cache optimization)
- Combine `RUN` commands to reduce layers
- Use `.dockerignore` to exclude unnecessary files, sensitive data, and build artifacts like `node_modules`

### Instructions (Essential)
- Use `COPY` instead of `ADD` (unless extracting archives)
- Set `WORKDIR` before `COPY`/`RUN`
- Use explicit `EXPOSE` for documentation
- Set meaningful `LABEL` metadata

### Additional Instructions
- Explicitly set `SHELL` if bash/sh features are needed
- Set environment variables with `ENV` for configuration (not secrets)
- Clean up package manager caches after install (e.g., `apt-get clean`)
- Understand `ENTRYPOINT` vs `CMD`: use `ENTRYPOINT` for main command, `CMD` for default args
- Document container usage with OCI labels (`org.opencontainers.image.*`)

### Health Checks
- Include `HEALTHCHECK` instruction
- Health check should verify app is actually working
- Set appropriate interval and timeout

### Example Good Dockerfile Pattern
```dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# Runtime stage
FROM node:20-alpine

# Add OCI labels for documentation
LABEL org.opencontainers.image.title="My App"
LABEL org.opencontainers.image.description="Production web application"
LABEL org.opencontainers.image.version="1.0.0"

RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app

# Copy dependencies and app files
COPY --from=builder /app/node_modules ./node_modules
COPY . .

# Set environment variables (not secrets)
ENV NODE_ENV=production

USER appuser
EXPOSE 3000
HEALTHCHECK CMD wget -q --spider http://localhost:3000/health || exit 1

# Use ENTRYPOINT for main command, CMD for default args
ENTRYPOINT ["node"]
CMD ["server.js"]
```
