About the Dockerfile Generator
Most Dockerfile problems are not syntax errors, they are layer-ordering and image-size problems that only show up once the image is being rebuilt fifty times a day in CI. This generator produces a Dockerfile with the ordering and the multi-stage structure already correct.
The rule that governs build speed is cache invalidation: every instruction is a layer, and changing one invalidates every layer after it. That is why dependency manifests should be copied and installed before the application source is copied. Source changes on every commit; dependencies change rarely. Copying everything at once means reinstalling all dependencies on every build.
The rule that governs image size is that layers are additive. Deleting a file in a later instruction does not reclaim the space, because the earlier layer still contains it — and anyone who pulls the image can still extract it. A secret written and then removed in a later step is still in the image.
Frequently asked questions
Why is my Docker build not using the cache?
Usually because the source is copied too early. If the whole working directory is copied before dependencies are installed, any change to any file invalidates the install layer and everything after it. Copy the dependency manifests first, install, then copy the source. The other frequent cause is a build argument or timestamp that changes every run, which invalidates from that point onward.
What is a multi-stage build and do I need one?
It is a Dockerfile with several FROM instructions, where later stages copy only the artefacts they need from earlier ones. The build stage carries the compiler, the package manager, and the full dependency tree; the final stage carries the binary and its runtime requirements. For any compiled language the difference is routinely an order of magnitude in image size, and it removes the build toolchain from the runtime attack surface.
Should I use alpine as a base image?
Sometimes. Alpine is small, but it uses musl instead of glibc, which breaks prebuilt binaries and can cause subtle differences in DNS resolution and locale handling. Python packages with C extensions often have no musl wheel and must compile from source, which makes builds far slower. The slim variants of Debian-based images are frequently the better trade.
How do I keep secrets out of the image?
Never write them into a layer. A secret that is added and then deleted in a later instruction is still recoverable from the earlier layer, and build arguments are visible in the image history. Use BuildKit secret mounts, which expose the value to a single RUN instruction without persisting it, and inject runtime configuration through the environment or a mounted file instead.
What is the difference between CMD and ENTRYPOINT?
ENTRYPOINT sets the executable and is not replaced by arguments passed at run time; CMD sets default arguments and is replaced. The common pattern is ENTRYPOINT for the binary and CMD for its default flags. Also prefer the exec form, written as a JSON array — the shell form wraps the process in a shell, which then swallows termination signals and leaves containers to be killed rather than shut down.
Need this managed for you, not just automated?
We're also a hands-on DevOps consultancy — Kubernetes, CI/CD, and cloud infrastructure.