Dockerfile Generator
Generate a working Dockerfile for a Node.js, Python, Go or static site project, with a custom base image, port and start command. Nothing is uploaded.
Worked examples
- A Node.js app with the default start command
The everyday case: a small Alpine-based Node image with dependencies installed before the rest of the source is copied in, so Docker's layer cache is reused across builds that only change application code.
- A Python app with a custom Gunicorn start command
Overriding the start command swaps the default `python app.py` for a production WSGI server, converted automatically into Docker's exec-form CMD array.
- A static site served by nginx
A static build (a Vite, Next.js export or plain HTML site) needs no install or start step — the built files are just copied into nginx's default web root.
What this tool does
This tool generates a working Dockerfile for a Node.js, Python, Go or static-site project from a handful of choices: the runtime, a base image tag, the port your app listens on, and an optional custom start command. The result is a complete, ready-to-use Dockerfile — not a fragment you have to assemble further — built from patterns that follow each ecosystem's normal conventions for layer caching and image structure.
When you need it
- Containerizing a project for the first time and wanting a correct starting point rather than piecing one together from scattered blog posts of varying quality and age.
- Standardizing how your team writes Dockerfiles across several small services, so each one follows the same base structure and can be reviewed quickly.
- Quickly producing a throwaway Dockerfile to test whether a project builds and runs in a container at all, before investing time in a more tailored, production-tuned version.
- Refreshing a stale Dockerfile — checking what a current, idiomatic version for a given runtime looks like, and comparing it against one that's grown outdated.
Why dependencies are copied before the rest of the source
Docker builds an image layer by layer, and caches each layer independently. The Node.js and Python templates deliberately copy just the dependency manifest (package*.json or requirements.txt) and install dependencies before copying the rest of the application source. As long as those dependency files haven't changed, Docker reuses the cached install layer on every subsequent build — even if you've changed application code a hundred times since. Reordering those two steps (copying everything first, then installing) would invalidate the cached install layer on every single code change, making every build reinstall every dependency from scratch.
Customizing the start command
The default start command for each runtime (npm start for Node, python app.py for Python, ./app for Go) covers the most common convention, but real projects vary — a production Node service might run through a process manager, and a Python app is often served by Gunicorn or Uvicorn rather than run directly. Enter your actual start command exactly as you'd type it on a command line, such as gunicorn app:app or node dist/server.js, and it's converted into Docker's exec-form CMD array, which is the recommended form because it runs the process directly rather than through a shell, so signals such as SIGTERM reach your app. Quotes are respected, so node server.js --name "my app" keeps my app as one argument. If the command needs a shell — it uses &&, |, ; or a $VARIABLE — the tool emits shell form (CMD npm run build && npm start) instead, since exec form never runs a shell.
Choosing the base image tag
The tag must exist on Docker Hub for the image the runtime selects: node:24-alpine, python:3.12-slim, golang:1.24-alpine or nginx:alpine. Because Python and Go tags begin with their own major version, the tool refuses a tag such as 20-alpine for those two runtimes instead of generating a Dockerfile that fails at docker build. Pick a Node version that is still in maintenance or long-term support; Node 20 reached end of life in April 2026, which is why the default is a newer release.
The static template
Choosing "static" produces a minimal nginx-based Dockerfile that copies your build output straight into nginx's default web root — the right shape for a pre-built single-page app, a static site generator's output, or any project where the container's only job is to serve already-built files. Note that EXPOSE is documentation only and does not change the port nginx listens on: the stock nginx image listens on 80, so leave the port at 80 for this template unless you also supply your own nginx configuration.
Limits
Each template is intentionally a straightforward single-stage build for clarity, not a fully hardened production image — it doesn't add a non-root user, health checks, or (for Go) a minimal multi-stage final image with just the compiled binary. Treat the output as a correct, working starting point to extend for your team's specific production requirements.
Frequently asked questions
- Is my project uploaded anywhere?
- No. The Dockerfile is assembled entirely in your browser from the options you choose; no source code or project details are sent anywhere.
- Why does the Node and Python template copy dependency files before the rest of the source?
- Docker caches each instruction as a layer. Copying package*.json or requirements.txt and installing dependencies before copying the rest of the code means that layer is reused on rebuilds unless dependencies actually changed, making iteration much faster.
- How do I change the start command?
- Enter it as you'd type it on a command line, such as `gunicorn app:app` or `node dist/server.js` — a plain command with quoted arguments is converted into Docker's exec-form CMD array. A command that needs a shell (it uses &&, |, ; or $VARIABLES) is emitted in shell form instead, because exec form does not run a shell.
- Does the Go template produce a small final image?
- No — this generates a straightforward single-stage build using the full golang image for clarity. For a minimal production image, add a second FROM stage that copies only the compiled binary into a smaller base image.