← Back to list

You’re Using Docker Wrong: Optimizing Containers for Production

Your Docker builds are slow, your images are bloated and security scans give you nightmares — sound familiar?

jude otine · 2025-05-26 07:11 · 16 claps · 3.0 min read
#docker-optimization #minimal-docker-images #secure-containers #multi-stage-builds #docker-best-practices
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud

You’re Using Docker Wrong: Optimizing Containers for Production

docker post image

docker post image

Your Docker builds are slow, your images are bloated and security scans give you nightmares — sound familiar?

You’re not alone. Many developers use Docker daily without realizing they’re dragging unnecessary baggage into production. Whether you’re shipping a monolith or microservices, unoptimized Docker images lead to longer build times, increased attack surfaces and costly deployments.

Let’s fix that.

In this post, we’ll dive into the most common Docker mistakes and give you practical, battle-tested strategies to streamline your containers for production. Whether you’re an engineer, DevOps lead or just Docker-curious, you’ll walk away with techniques you can apply today.

Common Docker Mistakes (And How They Hurt You)

Let’s start by diagnosing the usual suspects.

1. Bloated Images

You probably started your Dockerfile like this:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
    python3 \
    nodejs \
    curl

Looks fine until you realize your final image is over 600MB. Why?

  • You’re using a general-purpose base image.
  • You didn’t clean up temporary files.
  • You’re installing packages you may not need in production.

Better:

FROM python:3.11-slim
RUN apt-get update && apt-get install -y curl \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

This can shrink your image by over 60% compared to full Ubuntu.

2. Slow Builds

Docker caches layers — great in theory, terrible if misused.

What devs often do:

COPY . .
RUN npm install

If any file changes, the entire cache invalidates and npm install re-runs.

Fix:

Use .dockerignore and restructure your layers:

COPY package*.json ./
RUN npm install
COPY . .

This ensures npm install only runs when dependencies change not every time you tweak a file.

Also: Don’t forget to .dockerignore things like node_modules, .git, tests and .env.

3. Insecure Images

Too many containers are running with root privileges, old libraries and even hardcoded secrets.

ENV DB_PASSWORD=supersecret

Common mistakes:

  • Running as root by default.
  • Not updating the base image.
  • Committing secrets directly into Dockerfiles or .env files.

Fix:

  • Use USER directive.
  • Periodically update base images.
  • Use Docker secrets or external vaults.
RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
USER appuser

Running as a non-root user reduces the blast radius of potential vulnerabilities.

Optimization Strategies

Now let’s level up.

Minimal Images

Start from a lean base. Try:

FROM alpine:3.20
RUN apk add --no-cache curl

For compiled apps:

FROM gcr.io/distroless/base-debian10

Tip: Use Alpine with caution if your app depends on glibc. Not every app is Alpine-friendly.

Multi-Stage Builds

Build tools ≠ production runtime.

Without multi-stage:

FROM golang:1.21
WORKDIR /app
COPY . .
RUN go build -o main
CMD ["./main"]

Final image: ~900MB

With multi-stage:

# Build stage
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o main

# Runtime stage
FROM alpine:3.20
WORKDIR /app
COPY --from=builder /app/main .
CMD ["./main"]

Final image: ~20MB

Security Scanning

Don’t ship vulnerabilities. Use these tools:

| Tool                                           | Type               | Notes                       |
| ---------------------------------------------- | ------------------ | --------------------------- |
| [Trivy](https://github.com/aquasecurity/trivy) | CLI                | Fast, great for CI/CD       |
| [Snyk](https://snyk.io)                        | SaaS + CLI         | Dependency-focused scans    |
| Docker Scout                                   | Built-in (Desktop) | Image layer insights & CVEs |

Best Practices:

  • Automate scans in CI pipelines.
  • Use updated base images.
  • Regularly patch known CVEs.
trivy image my-app:latest

Advanced Tips

Cache Smarter

Order your Dockerfile commands from least to most frequently changed to maximize cache hits.

Good:

COPY package.json .
RUN npm install
COPY . .

Bad:

COPY . .
RUN npm install

Use BuildKit

BuildKit offers faster builds, better caching and advanced features.

Enable it:

DOCKER_BUILDKIT=1 docker build .

Use SSH forwarding securely:

# syntax=docker/dockerfile:1.4
FROM node:20
RUN --mount=type=ssh git clone git@github.com:your/private-repo.git

Handle Secrets the Right Way

Avoid:

ENV API_KEY=secret

Instead:

  • Use Docker secrets (Swarm/K8s)
  • Use Vault, Doppler, or AWS Secrets Manager

Conclusion: Think Like a Container Pro

To recap:

✅ Use slim or distroless base images ✅ Leverage multi-stage builds ✅ Avoid running as root ✅ Optimize layer order for caching ✅ Scan for vulnerabilities regularly ✅ Never hardcode secrets

Containers are only as good as the Dockerfiles behind them. By optimizing yours, you’re not just saving storage you’re improving startup times, security posture and developer velocity.

What’s Your Biggest Docker Pain Point?

Let me know in the comments. I’d love to write follow-ups based on real challenges


메타데이터
post_id
a37d72ce5be7
slug
youre-using-docker-wrong-optimizing-containers-for-production-a37d72ce5be7
url
https://medium.com/@judeotine/youre-using-docker-wrong-optimizing-containers-for-production-a37d72ce5be7
canonical_url
https://medium.com/@judeotine/youre-using-docker-wrong-optimizing-containers-for-production-a37d72ce5be7
author_url
https://medium.com/@judeotine
status
ok
fetched_at
2026-06-26 03:39:16