Smaller image

2 snippets in Docker

DKDocker

Multi-Stage Builds

DK · Dockerfile
Syntax
FROM <image> AS <stage>
...
FROM <image>
COPY --from=<stage> <src> <dest>
Example
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]

Note The final image only contains the layers from the last FROM stage. Build tools, dev dependencies, and source code from earlier stages are discarded, dramatically reducing image size. A Go API might go from 1.2GB (with SDK) to 15MB (static binary on scratch).

Combine RUN Commands

DK · Best Practices
Syntax
RUN command1 && command2 && command3
Example
# Good - single layer, cache cleaned:
RUN apt-get update \
    && apt-get install -y --no-install-recommends curl ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# Bad - three layers, cache stuck in layer 1:
# RUN apt-get update
# RUN apt-get install -y curl
# RUN rm -rf /var/lib/apt/lists/*

Note Separate RUN statements each create a layer. The rm in a later layer does not reduce the image size because the deleted files still exist in a previous layer. Always install and clean up in the same RUN command.

Frequently asked questions

How does Docker handle smaller image?
Docker covers this with 2 copy-ready snippets on this page. The "Multi-Stage Builds" snippet in Docker uses `FROM <image> AS <stage>`.
Which command does the Docker example use?
The "Multi-Stage Builds" snippet uses `FROM <image> AS <stage>`, from the Dockerfile section of the Docker cheat sheet.
What other Docker snippets are shown for "smaller image"?
Besides "Multi-Stage Builds", this page also shows "Combine RUN Commands".
Is there anything to watch out for?
Yes. For "Multi-Stage Builds": The final image only contains the layers from the last FROM stage. Build tools, dev dependencies, and source code from earlier stages are discarded, dramatically reducing image size. A Go API might go from 1.2GB (with SDK) to 15MB (static binary on scratch).