How to Optimize Dockerfiles for Faster Builds and Smaller Images
This guide explains practical Dockerfile optimization techniques—including using .dockerignore, minimizing layers, choosing lightweight base images, consolidating RUN commands, setting proper WORKDIR/CMD, leveraging ENTRYPOINT with exec, preferring COPY over ADD, and applying multi‑stage builds—to dramatically speed up image builds and reduce final image size.
Introduction
Dockerfile syntax is simple, but speeding up image builds, reducing image size, and improving readability require practical experience. This article provides a comprehensive set of Dockerfile best‑practice tips.
Goals
Faster build speed
Smaller Docker images
Fewer image layers
Effective use of cache
Improved Dockerfile readability
Simpler container usage
Key Recommendations
1. Create a .dockerignore file
<code>.git/</code><code>node_modules/</code>2. Run a single application per container
Running multiple processes in one container leads to long build times, large images, tangled logs, wasted resources, and zombie‑process issues. Use separate containers (e.g., via Docker Compose) for each service.
3. Combine RUN instructions
Each Dockerfile instruction creates a new layer. Merging related RUN commands reduces layers and improves cache reuse.
<code>FROM ubuntu</code><code>RUN apt-get update \</code><code> && apt-get install -y nodejs \</code><code> && cd /app \</code><code> && npm install</code>4. Avoid using the latest tag
Specify an immutable tag (e.g.,
ubuntu:16.04) to prevent unexpected changes when the upstream image updates.
<code>FROM ubuntu:16.04</code>5. Delete temporary files after each RUN
Remove package lists and other build‑time artifacts to keep the image lean.
<code>RUN apt-get update \</code><code> && apt-get install -y nodejs \</code><code> && rm -rf /var/lib/apt/lists/*</code>6. Choose an appropriate base image
For Node.js apps, use the official
nodeimage or an Alpine variant (
node:7-alpine) to minimize size.
<code>FROM node:7-alpine</code><code>ADD . /app</code><code>RUN cd /app && npm install</code><code>CMD npm start</code>7. Set WORKDIR and CMD correctly
<code>FROM node:7-alpine</code><code>WORKDIR /app</code><code>ADD . /app</code><code>RUN npm install</code><code>CMD ["npm","start"]</code>8. Use ENTRYPOINT (optional) with exec form
Exec form prevents an extra shell process and ensures proper signal handling.
<code>ENTRYPOINT ["./entrypoint.sh"]</code><code>CMD ["start"]</code>9. Use exec in entrypoint scripts
Calling
execreplaces the shell with the application process, allowing Docker to forward signals correctly.
<code>#!/bin/sh</code><code>trap "exit" TERM</code><code>while true; do date; sleep 1; done</code>10. Prefer COPY over ADD
COPY is simpler and only copies files; use ADD only when you need remote URLs or automatic extraction.
<code>COPY . /app</code>11. Order COPY and RUN wisely
Place the least‑changing instructions early to maximize cache hits. For example, copy
package.jsonfirst, run
npm install, then copy the rest of the source.
<code>FROM node:7-alpine</code><code>WORKDIR /app</code><code>COPY package.json /app</code><code>RUN npm install</code><code>COPY . /app</code><code>CMD ["npm","start"]</code>12. Set default environment variables, ports, and volumes
<code>ENV PROJECT_DIR=/app</code><code>WORKDIR $PROJECT_DIR</code><code>EXPOSE 3000</code><code>VOLUME /data</code>13. Use LABEL for image metadata
<code>LABEL maintainer="[email protected]"</code>14. Add HEALTHCHECK
<code>HEALTHCHECK CMD curl --fail http://localhost:$APP_PORT || exit 1</code>15. Multi‑stage builds
Multi‑stage builds let you compile in a heavyweight image and copy only the final artifact into a lightweight runtime image.
<code>FROM golang:1.7.3 AS builder</code><code>WORKDIR /src</code><code>RUN go build -o app .</code><code>FROM alpine:latest</code><code>COPY --from=builder /src/app /app</code><code>CMD ["/app"]</code>By applying these practices you can achieve faster builds, smaller images, and more maintainable Dockerfiles.
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.