Independent comparison · no paid rankings
Home / Blog / Lean Docker images: gain time without hiding dependencies
Technical

Lean Docker images: gain time without hiding dependencies

A 40 MB Alpine image speeds deploys — until a missing library or musl incompatibility breaks prod on Friday night. Slim down yes; hide dependencies no.

4 min read Updated Jun 25, 2026

CI pipeline drops from twelve to four minutes: the team switched to php:8.3-alpine, removed apt layers, and cut the image from 680 MB to 95 MB. Celebration follows. Three days later, GD fails to load a TrueType font — musl and missing libs — and the thumbnail generator outputs empty PNGs.

Lean images speed pull, deploy, and cold start. They do not automatically simplify your app. Confusing "small Dockerfile" with "understood stack" yields images that boot fast but fail silently on a prod edge case.

Size, layers, and what actually costs time

Docker ships incremental layers. A "heavy" image with good local cache may deploy faster than a "lean" one that invalidates everything each commit because COPY . . sits too high.

LeverTypical gainRisk
Alpine/slim base−50 to 80% sizelibc incompatibilities, missing packages
Multi-stageRemoves toolchain from runtimeForgetting runtime libs (ssl, tzdata)
.dockerignoreStable cacheExcluding a required build file
Combine RUN aptFewer layersHarder line-by-line patching

Measure pull + start time on your registry and host — not just docker images locally.

A lean untested image externalizes cost to midnight debugging.

Multi-stage: separate build and runtime

Classic PHP/Node pattern:

  1. Builder stage: composer install, npm run build, compile extensions.
  2. Runtime stage: copy vendor/, public/build/, compiled binaries only.

Do not copy .git, tests, dev node_modules, or docs. Ensure PHP runtime extensions (pdo_mysql, intl, opcache) install in the final stage, not only builder.

On hosting with private registry (Scaleway, GitLab, Harbor), compact finals also cut storage and egress — especially with ten microservices.

Alpine, slim, distroless: picking libc

Alpine (musl): very small, apk packages. Frequent issues with wkhtmltopdf, some PECL extensions, glibc-linked binaries.

Debian/Ubuntu slim (glibc): slightly heavier, more predictable PHP/Python ecosystem.

Distroless / scratch: minimal, often no shell — great for Go or Java, harder for PHP-FPM where debug matters.

Minimum test matrix: container start, health check, critical business path (image upload, PDF, TLS API call).

.dockerignore and hidden dependencies — the wrong way

An overly aggressive .dockerignore excluding composer.lock or config forces implicit composer update at build — "lean" but non-reproducible images.

Conversely, sending the whole repo without ignore bloats build context and breaks cache on every doc commit.

Explicitly list what enters context: lockfiles, patches, custom extensions. Document system libs in the Dockerfile (comment + RUN apk add --no-cache ...).

Security, CVEs, and "latest" images

FROM node:latest or php:8-apache without a patch tag bloats and obscures updates. Pin php:8.3.12-fpm-bookworm and automate rebuild on CVE.

Scan (Trivy, Grype) the final image — not just the Dockerfile. A minimal alpine base with vulnerable openssl is still risk.

The peak: lightness that hides misunderstanding

Saving pull time is worthless if you spend an hour reconstructing what the old Debian image implicitly installed.

Decide and move forward without blind spots

Document runtime libs, adopt multi-stage, pin bases, smoke-test in CI. Compare alpine vs slim on your stack, not a generic benchmark.

For registry hosting, CI runners, and Docker VPS in Europe, see our directory and compare tool. Guides cover container framing.

Release checklist: pull fresh image, run health, execute a business scenario, scan CVE — before celebrating megabytes saved.

Frequently asked questions

Is Alpine always the right choice for a lean image?

No — test musl vs glibc for your stack; debian-slim or distroless may be more stable.

What does a multi-stage build provide?

Separates build and runtime; the final image does not ship the toolchain.

How do I speed up pull without hurting security?

Layer cache, .dockerignore, pinned tags — speed comes from cache as much as size.

Should production images include a shell?

Debug vs attack surface trade-off; choose based on external observability capability.


A lean image is judged on Friday night deploy — not Monday morning docker images.

Compare European hosts

Filter by compliance, location and use case — then open the sheets to verify the real scope.

Browse the directory
Blog

Related reading

All articles →