Ttooleras
🐳

Dockerfile Generator

Developer Utilities

Generate production Dockerfiles for any stack — multi-stage, optimized, secure. Free, private — all processing in your browser.

Select project type

Dockerfile

Edit the Dockerfile above to customize it for your project. The template follows Docker best practices including multi-stage builds, non-root users, and health checks.

Advertisement

The Dockerfile Generator creates production-ready Dockerfiles for your tech stack following current best practices: multi-stage builds (separating build and runtime for smaller images), non-root user (security), explicit versions (reproducibility), proper layer ordering (efficient caching), .dockerignore (exclude secrets and build artifacts), and HEALTHCHECK (container orchestration readiness). Choose your stack — Node.js, Python, Java, Go, Rust, PHP, Ruby, .NET, nginx — and configure the specifics (runtime version, build tool, port, etc.). Output is a Dockerfile + .dockerignore + sample commands, ready to drop into your project.

A poorly-written Dockerfile produces images that are gigabytes in size (instead of 20-100 MB), rebuild slowly (cache misses), run as root (security risk), include build tools in production (attack surface), and leak secrets (credentials in layers). A well-written multi-stage Dockerfile achieves the opposite — small, fast, secure, reproducible. Most teams learn these patterns through trial and error; this generator bakes the best practices in. Perfect for new projects starting with containers, or migrating old Dockerfiles to modern patterns.

Dockerfile Generator — key features

10+ language stacks

Node.js, Python, Java, Go, Rust, PHP, Ruby, .NET, nginx, Apache. Each with language-specific best practices.

Multi-stage builds

Separate build and runtime stages for dramatically smaller production images (often 10x smaller).

Non-root user

Automatically uses non-root user. Security best practice for container runtime.

Layer caching optimization

Correctly orders COPY and RUN commands so Docker caching is maximized. Rebuilds skip unchanged layers.

Pinned base images

Pins to specific version (node:20.11.0-slim). Reproducible builds across environments.

.dockerignore included

Matching .dockerignore file. Excludes common build artifacts and secrets.

HEALTHCHECK

Production-ready health checks for Kubernetes, Docker Compose orchestration.

Sample build/run commands

Ready-to-copy commands: docker build, docker run, docker push. Including argument examples.

How to use the Dockerfile Generator

  1. 1

    Choose language/stack

    Node.js, Python, Java, Go, etc. Each has language-specific templates with correct package manager.

  2. 2

    Specify runtime version

    Pick explicit version (node 20.11, python 3.12, java 21). Pinning prevents supply chain issues.

  3. 3

    Configure app details

    Port, entrypoint, build command. Tool suggests defaults for each stack.

  4. 4

    Choose base image variant

    Default for each stack (slim for Node, alpine for Go). Override if you have specific needs.

  5. 5

    Add environment variables

    ENV vars your app needs. ARG for build-time vars. Secrets are flagged for external handling.

  6. 6

    Enable multi-stage

    Default on. For compiled languages (Go, Java), dramatically reduces image size.

  7. 7

    Copy generated files

    Download Dockerfile and .dockerignore. Plus sample build/run commands for your shell.

Common use cases for the Dockerfile Generator

New projects

  • Containerize a Node.js app: Multi-stage with npm ci, build step, production-only dependencies, non-root user.
  • Dockerize Python app: Multi-stage with pip install, non-root, uvicorn/gunicorn for production.
  • Containerize Go microservice: Tiny final image (just the compiled binary). Alpine or scratch base.
  • Static site with nginx: nginx:alpine with your static files. Minimal, fast, secure.

Migration

  • Modernize old Dockerfiles: Upgrade to multi-stage, add non-root user, pin versions, reduce size.
  • Migrate from single-stage: Separate build and runtime. Often 5-10x smaller final image.
  • Move from Ubuntu/Debian to Alpine: Smaller images at cost of glibc compatibility. Test carefully.
  • Move from unpinned to pinned versions: Reproducible builds. Prevents supply chain attacks from malicious updates.

DevOps and cloud

  • Kubernetes-ready images: Proper HEALTHCHECK, non-root, graceful shutdown handling.
  • Docker Compose development: Multi-service projects — one Dockerfile per service. Dev vs prod stages.
  • CI/CD integration: Optimized for BuildKit caching (DOCKER_BUILDKIT=1). Fast CI builds.
  • Cloud deployments: AWS ECR, GCP GCR, Azure ACR push commands included. Works with ECS, GKE, AKS.

Security and compliance

  • Minimize attack surface: Distroless or alpine bases have no shell, minimal packages — fewer CVEs.
  • Non-root enforcement: Dockerfile uses non-root user. Container orchestrators can enforce (K8s runAsNonRoot).
  • Read-only filesystem prep: Docker images designed for read-only rootfs. Writable volumes only where needed.
  • Secrets handling: Guide for using Docker secrets or runtime env vars, never hardcoded ENV.

Dockerfile Generator — examples

Node.js multi-stage

Production Express/Fastify app.

Input
Stack: Node.js 20, multi-stage, non-root
Output
FROM node:20-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:20-slim
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
USER node
CMD ["node", "server.js"]

Python FastAPI

Multi-stage Python app.

Input
Stack: Python 3.12, multi-stage
Output
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
EXPOSE 8000
ENV PATH=/root/.local/bin:$PATH
USER 1000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Go tiny image

Compiled binary in scratch.

Input
Stack: Go 1.22, scratch for runtime
Output
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server

FROM scratch
COPY --from=builder /app/server /server
EXPOSE 8080
CMD ["/server"]

nginx static site

Simple frontend app.

Input
nginx:alpine + static files
Output
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
HEALTHCHECK CMD wget -q --spider http://localhost || exit 1

Java Spring Boot

JAR-based deployment.

Input
Stack: Java 21, Maven
Output
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY . .
RUN mvn package -DskipTests

FROM eclipse-temurin:21-jre-alpine
COPY --from=builder /app/target/*.jar /app.jar
EXPOSE 8080
CMD ["java", "-jar", "/app.jar"]

.dockerignore

Companion file.

Input
Exclude build artifacts, secrets, IDE files
Output
node_modules
.git
.env
.env.local
*.log
dist/
coverage/
.vscode/
.idea/
.DS_Store
README.md

Technical details

Docker image best practices (2026):

1. Multi-stage builds:

The key insight: build stage needs compilers, dev dependencies, test tools. Runtime stage needs only the compiled artifact and minimal dependencies. Separate them:

```dockerfile
# Build stage
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Runtime stage
FROM node:20-slim
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
EXPOSE 3000
USER node
CMD ["node", "dist/server.js"]
```

Final image contains only compiled dist/ and production dependencies — not the entire node_modules with dev dependencies, not the build tools, not the source code.

2. Base image selection:

| Base | Size | Use when |
|---|---|---|
| node:20 | ~1 GB | Development, full flexibility |
| node:20-slim | ~250 MB | Production with Debian |
| node:20-alpine | ~180 MB | Smallest, with Alpine Linux (glibc incompatibility risks) |
| distroless/nodejs20 | ~150 MB | Most secure, no shell |

Alpine is smallest but has edge cases (musl libc vs glibc) that can break native dependencies. Slim (Debian-based) is the safer default for most cases.

3. Layer ordering for caching:

Layers are cached. Change to an upper layer invalidates all lower layers. Order from least-to-most-changing:

``
1. Base image (never changes)
2. System packages (rarely changes)
3. Package manifest (package.json, requirements.txt) — copy first
4. Dependencies (install after copying manifest)
5. Application source (copy last)
6. Build step
``

Copy manifest first, run install, THEN copy source. If only source changes, cached dependencies layer is reused.

4. Non-root user:

Running as root inside a container is a security risk. If the container is compromised, attacker has root in that container. Fix:

``dockerfile
RUN addgroup --system app && adduser --system --ingroup app app
USER app
``

Or use pre-provided non-root users: USER node (in node images), USER nobody, USER 1000.

5. .dockerignore file:

Excludes files from the build context (sent to Docker daemon). Essential:

``
node_modules
.git
.env
.DS_Store
*.log
dist/
coverage/
tests/
.vscode/
``

Without .dockerignore, your entire project directory (possibly including secrets in .env) is sent to the Docker build, slowing builds and risking security.

6. HEALTHCHECK:

Tell Docker/Kubernetes how to verify the container is healthy:

``dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
``

7. Security:

- Pin versions: FROM node:20.11.0 not FROM node:20 (prevents supply chain attacks).
- Don't put secrets in ENV or ARG — use docker secrets or runtime env vars.
- Use ARG for build-time only variables (not in final image).
- Scan with docker scan or Trivy for vulnerabilities.

8. ENTRYPOINT vs CMD:

- CMD is the default command. Overridden by docker run image other_command.
- ENTRYPOINT is the fixed command. docker run image args passes args to ENTRYPOINT.
- Use ENTRYPOINT for a main command + CMD for default args: ENTRYPOINT ["node"] CMD ["server.js"].

9. ARG vs ENV:

- ARG — build-time variable. Available only during build.
- ENV — runtime environment variable. Available in running container.
- Put build args at top; pass with docker build --build-arg NAME=value.

10. Image size reduction tricks:

- Use multi-stage (biggest savings).
- Combine RUN commands to reduce layers: RUN apt-get update && apt-get install -y pkg && rm -rf /var/lib/apt/lists/*.
- Use --no-install-recommends in apt-get.
- Clean package manager caches in the same layer.
- Use Alpine or distroless when possible.

Common problems and solutions

Running as root

Never run as root unless absolutely necessary. Every language image has a non-root user (node, www-data, etc.). Use USER directive. K8s can enforce with runAsNonRoot.

Gigantic image sizes

Single-stage builds include everything. Multi-stage separates build from runtime. 1 GB Node image becomes 200 MB multi-stage. 500 MB Go image becomes 15 MB with scratch.

Cache invalidation

COPY . . early in Dockerfile invalidates cache on every source change. Copy package manifest first, install dependencies, then copy source. Dependency changes are rare; source changes common. Separate them.

Not using .dockerignore

Without .dockerignore, entire directory (including .git, node_modules, tests, secrets in .env) sent to Docker daemon. Slow builds, security risk, huge build context. Always include .dockerignore.

Latest tag in production

FROM node:latest or node is non-reproducible — next build gets different version. Pin: FROM node:20.11.0-slim. Prevents supply chain attacks and ensures reproducibility.

Secrets in ENV/ARG

ENV SECRET=abc is visible in docker inspect and image layers forever. ARG SECRET=abc is visible during build. Use Docker secrets, runtime env vars, or external secret managers (HashiCorp Vault, AWS Secrets Manager).

apt-get cache not cleaned

RUN apt-get update && apt-get install -y pkg leaves /var/lib/apt/lists/* in the layer, inflating size. Always follow with rm -rf /var/lib/apt/lists/* in the same RUN.

ENTRYPOINT vs CMD confusion

ENTRYPOINT is the fixed command; CMD is default args. ENTRYPOINT ["node"] CMD ["server.js"] — run as node server.js. docker run image --inspect — run as node --inspect (CMD overridden). Use ENTRYPOINT for wrapper scripts.

Dockerfile Generator — comparisons and alternatives

Dockerfile generator vs hand-writing: Hand-writing gives maximum control but risks missing best practices (cache ordering, non-root, multi-stage). Generators bake in best practices. Good generator + understanding both wins.

Multi-stage vs single-stage: Multi-stage is 5-10x smaller images. More complex Dockerfile but dramatically better results. No reason to use single-stage for compiled languages in production.

Alpine vs Debian base: Alpine is smaller (~5 MB vs ~100 MB base). But musl libc (Alpine) vs glibc (Debian) incompatibility breaks some native dependencies (Python scientific stack, database drivers). Debian slim is safer default for most apps; Alpine for tight constraints.

Distroless vs Alpine: Distroless (Google) has no shell, no package manager, no userspace tools. Most secure. Alpine has a minimal shell. Distroless is better for production runtime; Alpine for dev/debugging.

Dockerfile vs Buildpacks: Buildpacks (Paketo, Heroku) generate Dockerfile automatically from your source. Less control but simpler. Good for uniform teams; Dockerfile for full control.

Dockerfile vs OCI image spec: OCI (Open Container Initiative) is the standard container image spec. All modern container runtimes (Docker, containerd, Podman, CRI-O) use OCI images. Dockerfile is the most common way to create them.

Docker Compose vs Dockerfile: Dockerfile defines one image; docker-compose.yml defines how multiple images run together. Both needed for multi-container apps.

Frequently asked questions about the Dockerfile Generator

What is a Dockerfile?

A Dockerfile is a text file with instructions that tell Docker how to build a container image. Contains commands (FROM, RUN, COPY, EXPOSE, CMD) that are executed in sequence. Each instruction creates a layer; final image is the combination of all layers. Essential for containerizing applications.

Why use multi-stage builds?

Build tools (compilers, dev dependencies) are needed to build your app but not to run it. Multi-stage separates: build stage has everything to compile. Runtime stage has only the compiled output. Final image is dramatically smaller (often 5-10x) and more secure (fewer tools = less attack surface).

Should I use Alpine or Debian-based images?

Debian slim (node:20-slim) is safer for most applications — full glibc compatibility, familiar package management. Alpine (node:20-alpine) is smaller but uses musl libc which can break native dependencies (Python scientific, certain database drivers). Start with Debian slim unless you need Alpine size reduction.

How do I make my image smaller?

(1) Multi-stage builds (biggest win). (2) Alpine base (if compatible). (3) Combine RUN commands (fewer layers). (4) Clean package manager cache in same RUN. (5) .dockerignore to exclude build context bloat. (6) Distroless for Go/Java production. Typical node image: 1 GB → 200 MB → 150 MB.

How does Docker layer caching work?

Each instruction in Dockerfile creates a layer. Docker caches layers — if nothing changed above a layer, the layer is reused. Change to an upper layer invalidates all below. Order commands from least-to-most changing: base → system packages → dependencies → source code.

Why should I run containers as non-root?

If an attacker compromises your application inside a container, being root means they have root inside that container. Non-root limits damage. Kubernetes can enforce runAsNonRoot: true. Security best practice since 2020+. Every modern language image has a non-root user pre-defined.

What goes in .dockerignore?

Anything not needed in the build: .git/, node_modules/, .env (secrets!), *.log, test output, IDE files (.vscode/, .idea/), README.md, docs/. Reduces build context size (faster builds) and prevents accidental secret leakage.

How do I handle secrets?

Never hard-code in Dockerfile (ENV/ARG). Options: (1) Docker secrets (Docker Swarm), (2) Runtime env vars (docker run -e SECRET=... or K8s Secret). (3) External secret managers (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager). Secrets in image layers are forever accessible.

What is the difference between ENTRYPOINT and CMD?

CMD is the default command, overridable: docker run image other_command. ENTRYPOINT is the fixed command; docker run image args passes args to it. Best practice: ENTRYPOINT for main executable, CMD for default args. Example: ENTRYPOINT ["node"] CMD ["server.js"].

Should I pin my base image version?

Yes. FROM node:20-slim is better than FROM node:latest (reproducibility), but still risky (new patch versions). FROM node:20.11.0-slim is fully pinned and reproducible. Trade-off: fully-pinned requires manual updates; partially-pinned gets automatic patches.

Additional resources

Advertisement

Learn more

Explore more tools

200+ free tools that run in your browser.

Browse all tools →