ReleaseRun · Docker 2026
5 Docker Mistakes That Break Production
Real patterns from real post-mortems. Each one is preventable — once you know it.
Tap to start →
1
Mistake 1 / 5
Pinning to :latest
It works until it doesn't. A dependency release over the weekend silently changed the image. Monday deployment breaks with a different Python version than last week.
FROM python:3.12.9-slim # not: FROM python:latest
✓ Always pin to an exact version
2
Mistake 2 / 5
Running containers as root
Default Docker containers run as UID 0. If an attacker escapes the container, they're already root on the host. Most apps don't need root at all.
RUN adduser --disabled-password appuser USER appuser
✓ Create a non-root user and switch to it
3
Mistake 3 / 5
Secrets baked into layers
Every RUN, COPY, and ADD creates a layer. Deleting a secret in a later layer doesn't remove it — it's still in the image history and readable via docker history.
RUN --mount=type=secret,id=npmrc \ npm install --ignore-scripts
✓ Use BuildKit --mount=type=secret
4
Mistake 4 / 5
No .dockerignore file
Without it, `docker build` sends your entire directory to the daemon — including .git (often 200MB+), node_modules, .env files with local secrets, and test fixtures.
.git node_modules .env *.log coverage/ .DS_Store
✓ Add .dockerignore to every repo
5
Mistake 5 / 5
Shipping the build toolchain
Single-stage builds ship compilers, test deps, and build caches to production. A Go app that's 8MB binary arrives as a 800MB image with the full Go toolchain.
FROM golang:1.24 AS builder RUN go build -o app . FROM gcr.io/distroless/static COPY --from=builder /app/app /app
✓ Multi-stage: build heavy, ship light
🐳
Know your Docker image health grades
ReleaseRun tracks version health, EOL status, and CVE exposure for 300+ technologies — including Docker base images.
Free Vuln Scanner →
Docker Reference Guide