Skip to main content

Docker Best Practices

Build secure, optimized, and production-ready Docker images and containers.

1. Security Best Practices

Don’t Run as Root

By default, Docker containers run as root. This is a security risk. Fix: Create a non-root user in your Dockerfile.
FROM node:18-alpine
WORKDIR /app
# Create user and group
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Set ownership
COPY --chown=appuser:appgroup . .
# Switch user
USER appuser
CMD ["node", "server.js"]

Keep Images Minimal

Smaller images have a smaller attack surface.
  • Use Alpine or Distroless images.
  • Remove build tools (compilers) after use (Multi-stage builds).

Scan for Vulnerabilities

Use tools like docker scan (powered by Snyk) or Trivy.
docker scan myapp:latest

2. Optimization & Performance

Leverage Build Cache

Order instructions from least changed to most changed.
  1. Install OS dependencies.
  2. Copy dependency manifests (package.json, go.mod).
  3. Install language dependencies.
  4. Copy source code.

Use .dockerignore

Prevent unnecessary files from being sent to the Docker daemon.
  • node_modules (install fresh in image)
  • .git (metadata not needed)
  • secrets.txt (never bake secrets into image!)

Multi-Stage Builds

Separate build environment from runtime environment.
# Build Stage
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# Runtime Stage
FROM gcr.io/distroless/static-debian11
COPY --from=builder /app/myapp /
CMD ["/myapp"]

3. Operational Best Practices

Healthchecks

Define how Docker checks if your container is healthy (not just running).
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:3000/health || exit 1

Logging

Log to stdout and stderr. Do not log to files inside the container.
  • Docker captures stdout automatically (docker logs).
  • Log drivers (Fluentd, Splunk) can ship these logs to a central system.

Graceful Shutdown

Handle SIGTERM signals in your application to shut down cleanly (close DB connections, finish requests).
  • Docker sends SIGTERM, waits 10s (default), then sends SIGKILL.

4. The “Golden Rules”

One Process Per Container

Don’t run a database and a web server in the same container. Use Compose.

Immutable Infrastructure

Never SSH into a container to patch it. Rebuild the image and redeploy.

Statelessness

Containers should be ephemeral. Store state in Volumes or external DBs.

Environment Config

Use Environment Variables for config, not hardcoded files.

🎉 Congratulations! You’ve completed the Docker Crash Course. Next: RabbitMQ Crash Course →