← IndexEntry № 096·coding

Generate a Production-Ready Dockerfile and Explain Each Line

Generate a hardened, multi-stage Dockerfile with line-by-line comments and matching .dockerignore.

Optimized for
ClaudeChatGPT
§ When to use this

This prompt produces a hardened, multi-stage Dockerfile for your stack with a comment on every line explaining why it's there, plus a matching .dockerignore and a note on runtime arguments. It's for developers who want a production-grade image — small, non-root, no leaked secrets — and who want to understand the decisions rather than copy-paste a black box. The hard constraints (multi-stage, slim base, dependency-layer caching, no secrets in the image) encode container best practices that are easy to get wrong, and the per-line comments turn the output into a learning artifact you can defend in code review.

§ The Prompt— fill in the fields, then copy or open in a tool
§ Customize0/1 fields filled
your prompt — fill the fields above
Write a production-grade Dockerfile for a [LANGUAGE/FRAMEWORK] application. Constraints: multi-stage build, non-root user, slim base image, layer caching for dependencies, no secrets in image. For each line, add a brief comment explaining WHY it's there. Also include a `.dockerignore` and a one-paragraph note on what runtime args to pass and why.
Open with your prompt →ChatGPTClaudeSends your filled-in prompt straight into a new chat.
§ Example Output

What you can expect back

# ---- Build stage ----
FROM node:20-slim AS build       # slim base: smaller, fewer CVEs than full image
WORKDIR /app
COPY package*.json ./            # copy manifests first so deps cache across code changes
RUN npm ci                       # ci = reproducible install from lockfile
COPY . .                         # copy source after deps for better layer caching
RUN npm run build                # produce build artifacts in this throwaway stage

# ---- Runtime stage ----
FROM node:20-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production          # disables dev behavior, trims dependencies
COPY --from=build /app/node_modules ./node_modules  # bring only built artifacts
COPY --from=build /app/dist ./dist                  # no source/build tools in final image
USER node                        # run as non-root to limit blast radius
EXPOSE 3000                      # document the port (does not publish it)
CMD ["node", "dist/server.js"]    # exec form so signals reach the process

.dockerignore:
node_modules
npm-debug.log
.git
.env
Dockerfile

Runtime note:
Pass secrets at runtime, never bake them in: docker run -e DATABASE_URL=... -p 3000:3000 myapp. Keeping .env out of the image (via .dockerignore) and injecting env vars at run time means the image stays generic and credentials never end up in a layer.

Illustrative example — your results will vary by tool and inputs.

§ Pro Tips

Get sharper results

  • 01Name the exact runtime version (Node 20, Python 3.12) so the base image tag is pinned and your builds stay reproducible instead of silently drifting.
  • 02Ask it to pin the base image by digest as well as tag if you need fully deterministic, supply-chain-hardened builds.
  • 03If your app needs build-time native dependencies, mention them so the build stage installs the right system packages and the runtime stage stays slim.
  • 04Have it add a HEALTHCHECK instruction tuned to your app's health endpoint so orchestrators can detect a hung container.
  • 05Request the equivalent docker build and docker run commands alongside the Dockerfile so you can test the multi-stage build end to end immediately.
§ Variations

Adapt it for your case

Distroless final stage

Ask it to use a distroless or scratch base for the runtime stage to shrink the image and attack surface even further.

With docker-compose

Add 'also write a docker-compose.yml wiring this service to a Postgres container with a named volume' for local development.

Static binary (Go/Rust)

Specify a compiled language and ask for a scratch-based final image containing only the static binary.

Use For — Tasks
Tags#docker#devops#deployment
§ FAQ

Common questions

Why a multi-stage build?

It lets you compile in a fat build stage with all the tooling, then copy only the finished artifacts into a clean runtime image, so build tools and source never ship to production.

How does this keep secrets out of the image?

Secrets are injected at runtime as environment variables (or via a secrets manager) and .env is excluded by .dockerignore, so credentials never get baked into a cached layer that could be extracted.

Will this image actually be small?

The slim base and multi-stage copy keep it lean, but final size depends on your dependencies; ask for a distroless or scratch variant if you need to minimize it further.

§ Related Entries

You may also need