Template · Docker

Production Dockerfile and Container Review Template

A fill-in review for a container going to production — base image and its update path, build stages, non-root user, secrets, image size, health checks, signals and the vulnerability position you are accepting.

Markdown. No sign-up, no email.

Fill this in for any image that will run in production. Most container incidents trace back to one of five things: running as root, secrets baked into layers, a base image nobody updates, no health check, or a process that ignores shutdown signals. This page is those five plus the detail around them.

Image: _______________ Owner (person): _______________ Date: _______ Registry: _______________

1. Base image#

Base image and tag
Pinned by digestyes / no
Why this base (not the default)
Size
Who rebuilds it when the base is patched
Rebuild cadence

🔴 :latest in production means the image you deploy on Friday is not the one you tested on Tuesday. Pin by digest, and own the update path deliberately — pinning without a rebuild schedule trades unpredictability for permanent staleness.

2. Build#

Multi-stage buildyes / no
Build tools present in the final imageyes / no — which
Layer order optimised (dependencies before source)yes / no
.dockerignore presentyes / no
Final image size
Reproducible from a clean checkoutyes / no

Anything in the final image that is not needed to run the application: _______________

Compilers, package managers and shells left in a runtime image are attack surface and download time. Everything in the image is something you now maintain.

3. Secrets#

  • [ ] No secrets in the Dockerfile
  • [ ] No secrets in build arguments
  • [ ] No secrets in any layer, including deleted files
  • [ ] No .env, .git, key material or cloud credentials copied in
  • [ ] Secrets injected at runtime from _______________

🔴 A file added in one layer and deleted in the next is still in the image. docker history and a layer inspection will find it, and so will anyone who pulls the image. If a secret was ever built into a published image, rotate it — deleting the image is not sufficient.

4. Runtime user and permissions#

Runs as userroot / _____ (uid)
Filesystem read-onlyyes / no
Writable paths required
Capabilities dropped
Privileged modeyes / no — why
Host paths mounted
Host network / PID namespace usedyes / no

Running as root is the default and almost never necessary. Create a user in the Dockerfile, give it ownership of only what it needs, and switch to it before the entrypoint.

5. Process behaviour#

PID 1 is the application, not a shellyes / no
SIGTERM handled — graceful shutdownyes / no
Shutdown grace period needed
In-flight work finished or requeued on shutdown
Restart policy

A container that ignores SIGTERM is killed after the grace period. Under a rolling deploy that means dropped requests or half-finished jobs on every release — a defect that only appears in production, and only under load.

6. Health and observability#

Liveness check
Readiness check (distinct from liveness)
Readiness actually checks dependenciesyes / no
Logs to stdout/stderr, not filesyes / no
Log format
Metrics exposed

Liveness answers "should this be restarted"; readiness answers "should this receive traffic". Wiring the same endpoint to both causes a restart loop the moment a dependency is briefly slow.

7. Resources#

RequestLimit
CPU
Memory

Memory limit set from measurement, not a guess: yes / no What the application does when it hits the limit: _______________ (Usually: killed abruptly. If the runtime has its own heap setting, it must be told about the container limit or it will size itself against the host.)

8. Vulnerabilities#

Image scanned on buildyes / no — tool
Scan result: critical ___ high ___
Accepted findings, with reasons
Who reviews scan results, and when
Base image rebuild triggers a rescanyes / no

Record the accepted risk explicitly. A scan whose output nobody reads is a build step, not a control.

9. Sign-off#

NameDate
Built by
Security review
Approved for production

Back to Docker