20 Common Docker Mistakes to Avoid and How to Fix

Docker has transformed the way we build, ship, and run applications. But like any powerful tool, it’s easy to misuse. Many developers (even seasoned ones) stumble into mistakes that lead to bloated images, security risks, or unpredictable deployments.
In this blog, we’ll explore 20 common Docker mistakes to avoid, along with practical fixes and best practices.
1. Running Containers as Root
Mistake: By default, containers run as root
, which poses security risks if compromised.
Fix: Add a non-root user in your Dockerfile:
RUN useradd -m appuser
USER appuser
2. Using the latest
Tag Everywhere
Mistake: Relying on :latest
makes builds unpredictable since the underlying image can change anytime.
Fix: Pin image versions (e.g., python:3.11-slim
) and update intentionally.
3. Ignoring Image Size
Mistake: Large images slow down builds, deployments, and waste bandwidth.
Fix:
Use slim or alpine images.
Multi-stage builds to discard build tools.
Clean caches with apt-get clean && rm -rf /var/lib/apt/lists/*
.
4. Not Using Multi-Stage Builds
Mistake: Keeping compilers, build dependencies, and temporary files in production images.
Fix:
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o main
FROM debian:bookworm-slim
COPY --from=builder /app/main /usr/local/bin/main
CMD ["main"]
5. Hardcoding Secrets in Dockerfile
Mistake: Adding API keys, passwords, or tokens in Dockerfiles or ENV variables.
Fix: Use secret managers (AWS Secrets Manager, Vault, Kubernetes secrets) and pass them at runtime.
6. Not Using .dockerignore
Mistake: Sending unnecessary files (node_modules, logs, .git) to the build context.
Fix: Create a .dockerignore
:
.git
node_modules
*.log
7. Copying Everything in Dockerfile
Mistake: Using COPY . .
blindly includes extra files.
Fix: Be explicit:
COPY package.json yarn.lock ./
RUN yarn install
COPY src/ ./src
8. Not Layering Commands Efficiently
Mistake: Each Dockerfile instruction creates a new layer, bloating the image.
Fix: Combine related commands:
RUN apt-get update && apt-get install -y \
curl wget git \
&& rm -rf /var/lib/apt/lists/*
9. Overusing ADD
Instead of COPY
Mistake: ADD
has hidden behaviors (e.g., auto-extraction) that aren’t always needed.
Fix: Use COPY
unless you specifically need ADD
.
10. Not Setting Health Checks
Mistake: Containers can be running but unhealthy, and Docker won’t know.
Fix:
HEALTHCHECK CMD curl -f http://localhost:8080/ || exit 1
11. Ignoring Logs
Mistake: Writing logs to files inside containers makes them inaccessible.
Fix: Write logs to stdout
/stderr
so Docker logging drivers can capture them.
12. Forgetting About Resource Limits
Mistake: Containers without limits can consume all CPU/memory.
Fix: Use:
docker run --memory=512m --cpus=1 myapp
13. Running Too Many Processes in One Container
Mistake: Treating containers like VMs and running multiple unrelated processes inside.
Fix: Follow “one process per container”. Use Docker Compose or Kubernetes to orchestrate multiple services.
14. Using Containers for Persistent Storage
Mistake: Storing database data directly inside containers.
Fix: Use volumes or external storage for persistence.
docker run -v db_data:/var/lib/postgresql/data postgres
15. Neglecting Security Updates
Mistake: Using old base images full of vulnerabilities.
Fix:
Regularly rebuild images.
Use docker scan
or tools like Trivy to check vulnerabilities.
16. Building Images Without Caching in Mind
Mistake: Putting frequently changing layers (like source code) before dependencies, invalidating cache.
Fix: Order Dockerfile steps properly: install dependencies first, then copy source code.
17. Ignoring Networking Basics
Mistake: Hardcoding IPs or using localhost
when linking containers.
Fix: Use Docker networks:
docker network create appnet
docker run --network appnet myapp
18. Not Cleaning Up Dangling Images/Volumes
Mistake: Unused images, volumes, and containers pile up, wasting disk.
Fix:
docker system prune -af
docker volume prune
19. Forgetting About Multi-Architecture Builds
Mistake: Building only for amd64
, which breaks on ARM (Raspberry Pi, Apple M1/M2).
Fix: Use docker buildx
:
docker buildx build --platform linux/amd64,linux/arm64 -t myapp .
20. Skipping Documentation & Version Control for Dockerfiles
Mistake: No comments, no versioning, no clarity.
Fix: Document decisions in the Dockerfile and keep it in source control alongside your app.
Final Thoughts
Docker is simple to get started with but tricky to master. These 20 mistakes are among the most common pitfalls developers face. By adopting these best practices—secure, lean, and well-documented Dockerfiles—you’ll avoid headaches in production and ensure smoother deployments.
What Docker mistakes have you made before? Drop them in the comments—I’d love to hear your stories!
Comments (0)
No comments yet. Be the first to share your thoughts!