Dockerfile Optimization
Write efficient Dockerfiles for smaller images, faster builds, and better security.
Layer Optimization
Minimize Layers
# Bad: Multiple RUN commands
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y wget
RUN rm -rf /var/lib/apt/lists/*
# Good: Combined RUN command
RUN apt-get update && \
apt-get install -y \
curl \
wget && \
rm -rf /var/lib/apt/lists/*Order for Cache Efficiency
# Bad: Busting cache early
COPY . /app
RUN npm install
# Good: Dependencies first
COPY package*.json /app/
RUN npm ci
COPY . /appImage Size Reduction
Use Minimal Base Images
# Size comparison:
# ubuntu:22.04 ~77MB
# debian:slim ~80MB
# alpine:3.19 ~7MB
# distroless ~2MB
FROM node:20-alpine # Not node:20 (~1GB)
FROM python:3.12-slim # Not python:3.12 (~1GB)
FROM golang:1.22-alpine # For build stageClean Up in Same Layer
# Bad: Files persist in earlier layer
RUN apt-get update
RUN apt-get install -y build-essential
RUN make
RUN rm -rf /var/lib/apt/lists/*
# Good: Clean up in same layer
RUN apt-get update && \
apt-get install -y build-essential && \
make && \
apt-get purge -y build-essential && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*Use .dockerignore
# .dockerignore
.git
.gitignore
node_modules
npm-debug.log
Dockerfile*
docker-compose*
.env
*.md
.vscode
.idea
__pycache__
*.pyc
.pytest_cache
coverage
.coverageSecurity Best Practices
Run as Non-Root
# Create and use non-root user
RUN addgroup --gid 1001 --system appgroup && \
adduser --uid 1001 --system --ingroup appgroup appuser
USER appuser
# Or use existing user
USER nobodyDon't Store Secrets
# Bad: Secrets in image
ENV API_KEY=secret123
COPY credentials.json /app/
# Good: Use build secrets or runtime injection
RUN --mount=type=secret,id=api_key cat /run/secrets/api_key
# Or inject at runtime
# docker run -e API_KEY=$API_KEY myappUse Specific Versions
# Bad: Unpredictable
FROM node:latest
RUN npm install express
# Good: Pinned versions
FROM node:20.10.0-alpine3.19
RUN npm install [email protected]Build Performance
Use BuildKit
# Enable BuildKit
export DOCKER_BUILDKIT=1
# Or per-build
DOCKER_BUILDKIT=1 docker build -t myapp .Parallel Operations
# syntax=docker/dockerfile:1.4
FROM node:20-alpine
# Parallel downloads
RUN --mount=type=cache,target=/root/.npm \
npm ci --prefer-offlineCache Mounts
# Cache package manager data
RUN --mount=type=cache,target=/var/cache/apt \
apt-get update && apt-get install -y curl
# Cache npm
RUN --mount=type=cache,target=/root/.npm \
npm ci
# Cache pip
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txtOptimization Checklist
| Category | Practice |
|---|---|
| Base Image | Use minimal (alpine, slim, distroless) |
| Layers | Combine RUN commands |
| Caching | Order from least to most changing |
| Size | Clean up in same layer |
| Security | Run as non-root user |
| Secrets | Never embed in image |
| Versions | Pin base image and dependencies |
| Context | Use .dockerignore |
- dockerfile
- optimization
- layers
- caching
- security