Boost Dockerfile Efficiency: Faster Builds, Smaller Images, Cleaner Containers
This guide explains how to write efficient Dockerfiles by using .dockerignore, minimizing layers, combining RUN commands, selecting lightweight base images, cleaning up after installations, setting proper WORKDIR and CMD, leveraging ENTRYPOINT with exec, preferring COPY over ADD, and applying multi‑stage builds to achieve faster builds and smaller, more maintainable images.
Goal
Faster build speed
Smaller Docker image size
Fewer image layers
Effective use of image cache
Improved Dockerfile readability
Simpler container usage
Key Practices
Create a
.dockerignorefile to exclude unnecessary files from the build context.
Run a single application per container; use Docker Compose to combine multiple services.
Combine related
RUNstatements into a single layer to reduce image size and improve caching.
Avoid using the
latesttag for base images; pin a specific version (e.g.,
ubuntu:16.04or
node:7-alpine).
Delete temporary files after each
RUN(e.g.,
rm -rf /var/lib/apt/lists/*).
Prefer lightweight base images such as
alpineor language‑specific images (e.g.,
node).
Set
WORKDIRand use JSON‑array syntax for
CMDto avoid shell parsing issues.
Optionally use
ENTRYPOINTwith
execso the container PID 1 correctly forwards signals.
Prefer
COPYover
ADDunless you need remote download or archive extraction.
Order
COPYand
RUNso that rarely‑changing layers appear early, maximizing cache reuse.
Define default environment variables, expose ports, and declare volumes as needed.
Use
LABELto add image metadata (author, description, etc.).
Add a
HEALTHCHECKto monitor container health.
Leverage multi‑stage builds to keep final images minimal and avoid shipping build‑time dependencies.
Example: Simple Optimized Dockerfile
<code>FROM node:7-alpine
WORKDIR /app
COPY package.json /app
RUN npm install && rm -rf /var/lib/apt/lists/*
COPY . /app
ENTRYPOINT ["./entrypoint.sh"]
CMD ["start"]
</code>Multi‑Stage Build Example (Go)
<code>FROM golang:1.7.3 AS builder
WORKDIR /go/src/app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root
COPY --from=builder /go/src/app/app .
CMD ["./app"]
</code>Using an Init System (tini)
<code>FROM alpine:3.7
COPY popcorn.sh .
RUN chmod +x popcorn.sh && apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--", "./popcorn.sh"]
</code>Running the Image
<code>docker build -t myapp .
# Development container
docker run -it --rm myapp dev
# Production container
docker run -d --restart always myapp start
</code>By following these guidelines you can achieve significantly faster Docker builds, smaller images, and more maintainable container deployments.
Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.