Dockerfile Generator
Pick a stack and get a sensible, multi-stage-aware Dockerfile — plus a matching .dockerignore
# ── Build stage ────────────────────────────────────────────── FROM node:22-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # ── Runtime stage ──────────────────────────────────────────── FROM node:22-alpine WORKDIR /app ENV NODE_ENV=production COPY package.json package-lock.json ./ RUN npm ci --omit=dev COPY --from=builder /app/dist ./dist EXPOSE 3000 CMD ["npm", "start"]
About this tool
The ToolNinja Dockerfile Generator builds a working Dockerfile from a few picks — stack, version, package manager, and a couple of commands — rather than starting from a blank file or copy-pasting one from an old project that may not fit. For Node.js and static sites, it defaults to a multi-stage build: a builder stage installs dependencies and runs your build step, then a clean runtime stage copies only the built output across, keeping the final image free of devDependencies and build tooling. Go gets a multi-stage build by default too, compiling a static binary in a Go image and running it from a minimal Alpine base. Python uses a single-stage Dockerfile, which is standard for most Python deployments. Every option also generates a matching .dockerignore, so node_modules, .git, and other directories that shouldn't be copied into the build context are excluded from the start.
When to use it
- →Scaffolding a Dockerfile for a new Node.js, Python, Go, or static-site project
- →Getting a correct multi-stage build pattern without copying one from an old repo
- →Generating a matching .dockerignore alongside the Dockerfile
- →Comparing single-stage vs. multi-stage image size tradeoffs before committing to one
Tips
- ◆Multi-stage builds keep your final image free of build tools and devDependencies — meaningfully smaller and with a smaller attack surface in production.
- ◆The alpine base variant produces the smallest images, but if a native dependency fails to install, try slim or full — alpine's musl libc occasionally trips up packages that expect glibc.
- ◆For the Go stack, the compiled binary runs from a bare Alpine runtime image with just ca-certificates added — no language runtime is needed at all for a statically compiled Go binary.
Frequently asked questions
Why use a multi-stage build instead of one FROM line?
A single-stage image carries every build tool, dev dependency, and intermediate file into the final image, even though none of that is needed at runtime. A multi-stage build throws all of that away after the build step, copying only the compiled output into a clean runtime image — often cutting final image size by more than half.
Do I need to edit the generated Dockerfile at all?
Treat it as a correct starting point, not a guaranteed final answer — it covers the common case for each stack, but project-specific needs (extra system packages, a monorepo structure, a non-standard entrypoint) will usually need a small manual tweak.
Why is the Python Dockerfile single-stage while Node and Go are multi-stage?
Python doesn't have a separate compile step the way a bundler or Go's compiler does — pip installs land directly in the runtime environment, so there's no intermediate build artifact to copy across stages, making a single stage the standard approach.