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.

Related tools

🥷 ToolNinja