Checklist · Docker

Container Image & Runtime Checklist

Build an image that is small, reproducible and safe to run, the build rules that matter, what must never be baked in, and the runtime settings that are wrong by default.

Markdown. No sign-up, no email.

Image / service: _______________ Date: _______

1. Base image#

  • [ ] Pinned by digest, not by tag, a tag moves, a digest does not
  • [ ] Minimal base chosen deliberately (distroless, slim, alpine) with the reason recorded
  • [ ] Base image comes from a source you would name in an audit
  • [ ] Base updated on a schedule, not when something breaks
  • [ ] Not latest anywhere in the file

An image built from FROM node:latest is a different image every week. The version running is not the version anyone approved.

2. Build#

  • [ ] Multi-stage build. Build tools do not reach the final image
  • [ ] Dependency install is its own layer, before the source copy, so the cache survives a code change
  • [ ] .dockerignore present, .git, node_modules, secrets, test fixtures
  • [ ] Build is reproducible: same inputs, same image
  • [ ] No apt-get upgrade in the build, upgrade the base instead, or the image drifts
  • [ ] Package lists cleaned in the same layer they were created

3. Secrets: what must never be in an image#

  • [ ] No credentials in ENV, ARG, or any layer. Layers are readable by anyone with the image, including deleted files
  • [ ] No .env file copied in
  • [ ] No private keys, certificates or tokens
  • [ ] No .git directory
  • [ ] Build-time secrets use the build secret mount, not ARG
  • [ ] Image scanned for secrets in the pipeline

A secret added in one layer and deleted in the next is still in the image. Deletion adds a layer; it does not remove one.

4. Runtime identity and filesystem#

  • [ ] Runs as a non-root user, created in the image
  • [ ] USER set, the default is root and the default is wrong
  • [ ] Read-only root filesystem, with writable volumes only where needed
  • [ ] No --privileged
  • [ ] Capabilities dropped, then added back only if required
  • [ ] no-new-privileges set

5. Size and layers#

  • [ ] Final image size recorded and justified
  • [ ] Nothing installed that is not needed at runtime, no compilers, no shells you do not use
  • [ ] Layers ordered least-changing to most-changing
  • [ ] Image inspected once by hand, you know what is in it

6. Configuration#

  • [ ] Configuration from environment or a mounted file, never baked in
  • [ ] The same image runs in every environment
  • [ ] Sensible defaults, with required values failing loudly at startup rather than defaulting to something wrong

7. Process behaviour#

  • [ ] One process concern per container
  • [ ] Process runs in the foreground, PID 1 handles signals, or an init is used
  • [ ] Responds to SIGTERM and shuts down cleanly within the grace period
  • [ ] In-flight work is finished or handed back on shutdown
  • [ ] Logs to stdout and stderr, not to files inside the container

A container that ignores SIGTERM is killed after the grace period. Every rolling update then drops whatever it was doing.

8. Health and resources#

  • [ ] Readiness check. Can it serve right now?
  • [ ] Liveness check. The process only, never a dependency
  • [ ] Memory limit set, from measurement
  • [ ] CPU request set, from measurement
  • [ ] Behaviour under the memory limit understood, a runtime that does not see the limit will exceed it

9. Supply chain#

  • [ ] Image scanned for known vulnerabilities in the pipeline, and the result blocks
  • [ ] Dependency manifest committed and reviewed
  • [ ] Image signed, or its digest recorded in the deployment record
  • [ ] Registry access controlled and audited
  • [ ] Retention policy on old images, registries grow without limit

10. The traps#

  • [ ] Not treating the container as a small server, no SSH, no cron inside, no manual fixes
  • [ ] No state on the container filesystem. It is gone on restart
  • [ ] Not running as root because it was easier
  • [ ] Not copying the whole build context because .dockerignore was skipped
  • [ ] Not using the same image with an environment variable that changes behaviour dangerously

Sign-off#

NameDate
Built by
Reviewed by

Back to Docker

Get new material when it is published

Everything here is free and stays free. There is no form in front of any document. If you want to know when new guides and templates go up, leave an email.

Roughly monthly. Unsubscribe in one click. We do not share your address, and we will not call you.