home / skills / yldgio / codereview-skills / docker

docker skill

/skills/docker

This skill guides Dockerfile best practices, security hardening, and multi-stage builds to optimize images and reduce risk.

npx playbooks add skill yldgio/codereview-skills --skill docker

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
2.8 KB
---
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"]
```

Overview

This skill provides actionable Dockerfile best practices focused on security hardening, multi-stage builds, and image optimization. It guides reviewers and authors to produce smaller, safer, and more maintainable container images. The guidance balances security controls, build performance, and runtime reliability.

How this skill works

The skill inspects Dockerfile patterns and recommends concrete changes: pinning base images, enforcing non-root execution, minimizing layers with multi-stage builds, and removing secrets from images. It highlights risky constructs (privileged mode, build-time injection vectors, ADD misuse) and suggests fixes like .dockerignore, cache-friendly instruction ordering, and health checks. Output is practical advice you can apply directly to CI/CD pipelines or code reviews.

When to use it

  • When creating or reviewing Dockerfiles for production services
  • Before merging changes that modify base images, build args, or RUN chains
  • When reducing image size or improving CI build cache performance
  • When hardening container runtime security for compliance or ops
  • When adding or validating container health checks and metadata

Best practices

  • Pin base images to explicit versions and use trusted official or minimal images (alpine/slim/distroless)
  • Run processes as a non-root user (USER directive) and avoid --privileged unless justified
  • Use multi-stage builds to keep final images minimal and COPY instead of ADD unless extracting archives
  • Keep secrets out of images; inject them at runtime and avoid sourcing untrusted build-time variables
  • Order Dockerfile instructions by change frequency, combine RUN steps to reduce layers, and use .dockerignore
  • Include HEALTHCHECK that verifies real app functionality, add OCI labels, and clean package caches

Example use cases

  • Converting a development Dockerfile into a production-ready multi-stage build
  • Auditing CI pipelines for build-arg injection risks and secret leakage
  • Reducing image size and startup time by removing build tools and caches from the runtime image
  • Hardening container deployments by enforcing non-root users and read-only root filesystems
  • Adding robust health checks and OCI metadata for observability and supply-chain documentation

FAQ

Should I ever use ADD?

Only when you need its archive extraction or remote URL fetch behavior; prefer COPY for predictable file copying.

How do I manage secrets if not in the image?

Inject secrets at runtime via environment variables managed by your orchestrator, secret mounts, or a secrets manager; never bake them into ENV or source files.