0
0
MLOpsdevops~5 mins

Multi-stage builds for smaller images in MLOps - Commands & Configuration

Choose your learning style9 modes available
Introduction
Building container images can create large files if all build tools and files stay in the final image. Multi-stage builds let you use multiple steps to build your app, but only keep the final needed files. This makes your images smaller and faster to download.
When you want to compile code inside a container but don't want the compiler in the final image.
When your app needs temporary files or tools only during build time, not at runtime.
When you want to reduce image size to save bandwidth and storage.
When you want to improve security by excluding build tools from the final image.
When you want to speed up deployment by having smaller images to pull.
Config File - Dockerfile
Dockerfile
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o my-app

FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/my-app .
CMD ["./my-app"]

This Dockerfile has two stages:

  • builder: Uses the golang image to compile the Go app.
  • final: Uses a small Alpine Linux image and copies only the compiled app from the builder stage.

This keeps the final image small by excluding the Go compiler and source code.

Commands
Builds the Docker image using the multi-stage Dockerfile in the current directory. The image is tagged as my-app:1.0.
Terminal
docker build -t my-app:1.0 .
Expected OutputExpected
Sending build context to Docker daemon 5.12MB Step 1/6 : FROM golang:1.20 AS builder ---> 3a2f3b1f4c7a Step 2/6 : WORKDIR /app ---> Using cache ---> 7c9f1e2a3b4d Step 3/6 : COPY . . ---> 1a2b3c4d5e6f Step 4/6 : RUN go build -o my-app ---> Running in 9f8e7d6c5b4a Removing intermediate container 9f8e7d6c5b4a ---> 8a7b6c5d4e3f Step 5/6 : FROM alpine:3.18 ---> 5d8f7e6c4b3a Step 6/6 : COPY --from=builder /app/my-app . ---> Using cache ---> 2b3c4d5e6f7a Successfully built 2b3c4d5e6f7a Successfully tagged my-app:1.0
Shows the size and details of the built image to verify it is smaller than a full build image.
Terminal
docker images my-app:1.0
Expected OutputExpected
REPOSITORY TAG IMAGE ID CREATED SIZE my-app 1.0 2b3c4d5e6f7a 10 seconds ago 12MB
Runs the built image to verify the app starts correctly with only the necessary files.
Terminal
docker run --rm my-app:1.0
Expected OutputExpected
No output (command runs silently)
--rm - Automatically remove the container after it stops
Key Concept

If you remember nothing else from this pattern, remember: multi-stage builds let you separate build steps so only the final needed files go into your container image, making it smaller and cleaner.

Common Mistakes
Copying all source files directly into the final image instead of using a builder stage.
This makes the final image large and includes unnecessary build tools and files.
Use a builder stage to compile or build your app, then copy only the final output into a clean base image.
Not naming the build stage and trying to copy from an unnamed stage.
Docker cannot find the source files to copy, causing build errors.
Name your build stage with AS and use that name in the COPY --from= stage.
Summary
Use multi-stage builds to separate building your app and creating the final image.
Build your app in a full environment, then copy only the needed files to a small base image.
This reduces image size, improves security, and speeds up deployment.