docker
Dockerfile Generator
Generate a production-ready Dockerfile for Node.js, Python, Go, Rust, or Java. Supports multi-stage builds, non-root users, and minimal base images.
Dockerfile Best Practices
A well-written Dockerfile produces a small, secure, cacheable image. Here are the key patterns used in this generator.
Layer Caching
Docker caches each layer. Put rarely-changing layers first:
# Good — package.json copied before source code
COPY package*.json ./
RUN npm ci
COPY . . # ← only this layer invalidates on code change# Bad — all layers rebuild on every code change COPY . . RUN npm ci ```
Multi-Stage Builds
FROM node:20-alpine AS builder
RUN npm ci && npm run buildFROM node:20-alpine AS runner COPY --from=builder /app/.next ./.next # Build tools stay in builder, not in runner ```
Non-Root User
RUN addgroup --system --gid 1001 appgroup && adduser --system --uid 1001 appuser
USER appuserSignal Handling (exec form)
# Good — process receives SIGTERM directly
CMD ["node", "server.js"]# Bad — SIGTERM goes to shell, not node CMD node server.js ```
Frequently Asked Questions
Why use multi-stage builds?
Multi-stage builds separate the build environment (compiler, dev dependencies) from the runtime image. A Node.js app might need 500 MB of build tools but only 50 MB to run. Multi-stage reduces the final image size by 5–10× and removes build tools that could be exploited.
Why run as a non-root user?
By default Docker containers run as root inside the container. If an attacker escapes the container, they have root access to the host. Running as a non-root user (UID 1001) limits blast radius. Kubernetes also enforces non-root via PodSecurityContext.
What's the difference between CMD and ENTRYPOINT?
ENTRYPOINT sets the executable that always runs. CMD sets default arguments that can be overridden at runtime. Best practice: use ENTRYPOINT for the binary and CMD for default flags. For shell scripts use CMD ["node", "server.js"] (exec form, not shell form) to avoid PID 1 issues with signals.
Why does Go use 'FROM scratch'?
Go compiles to a fully static binary (CGO_ENABLED=0). The scratch image is literally empty — no shell, no libc, nothing. This produces the smallest possible image (~5–10 MB) and the smallest attack surface. The only caveat: you need to copy CA certificates for TLS.