Docker packages applications into portable container images. Dockerfile best practices: multi-stage builds (separate build and runtime images), layer caching (order instructions from least to most changed), minimal base images (distroless, alpine), non-root user for runtime, pinned base image versions. BuildKit enables parallel build stages, secret mounts, and cache mounts. The docker-compose file defines multi-service local development environments.
Optimal Dockerfile instruction order for maximum cache hits.
A Node.js app with devDependencies is ~400MB. The runtime with only node_modules prod deps is 80MB. Multi-stage: your final image has no webpack, tsc, or test frameworks.
Container processes running as root can write to the host if there's a container escape vulnerability. Add USER 1001 (non-zero UID) before CMD in every production Dockerfile.
FROM node:20-alpine can change with a new alpine patch. FROM node:20.11.0-alpine3.19 is reproducible. For the most stability, pin by digest: FROM node@sha256:abc123...
Sign in to share your feedback and join the discussion.