Multi-Stage Builds In Docker: Save Image Size And Improve Security

Docker multi-stage builds help developers create smaller, cleaner, and more secure images by separating the build environment from the final runtime. In this post, you’ll learn what multi-stage builds in Docker are and how to use them effectively.

Why Use Multi-Stage Builds in Docker?

Normally, when you build an image that compiles code (e.g., with gcc, npm, or go build), those tools and dependencies stay in the final image — even if they’re no longer needed at runtime.

This leads to:

  • 🚫 Unnecessary bloat
  • 🛡️ Higher security risks
  • 🐌 Slower deploys

Multi-stage builds solve this by using multiple FROM statements in a single Dockerfile — copying only the final output from the build phase into a clean runtime environment.

Example: Python App Using Poetry for Dependency Management

Let’s say you have a simple Python app that uses Poetry for dependency management.

Create a file named pyproject.toml:

[tool.poetry]
name = "hello-docker"
version = "0.1.0"
description = ""
authors = ["You"]

[tool.poetry.dependencies]
python = "^3.11"

[tool.poetry.scripts]
hello = "app:main"

Next, create app.py:

def main():
    print("Hello from a Python multi-stage Docker build!")

if __name__ == "__main__":
    main()

Dockerfile with Multi-Stage Build

# Stage 1: Build using Poetry
FROM python:3.11-slim AS builder

RUN pip install poetry

WORKDIR /app

COPY pyproject.toml .
COPY app.py .

# Install only dependencies, skip installing current project
RUN poetry config virtualenvs.create false \
    && poetry install --only main --no-root --no-interaction

# Stage 2: Clean runtime image
FROM python:3.11-alpine

WORKDIR /app

COPY --from=builder /app /app

CMD ["python", "app.py"]

Build and Run

docker build -t python-multistage .
docker run --rm python-multistage
Multi-Stage Builds In Docker build

Expected output:

Hello from a Python multi-stage Docker build!
Multi-Stage Builds In Docker run

Size Comparison (Approximate)

MethodImage Size
Without multi-stage~300MB
With multi-stage~30MB 🧨

Benefits Recap

  • 🧼 Clean final images — no compilers or build tools
  • 📦 Smaller image sizes = faster CI/CD and deploys
  • 🔐 Lower attack surface = better security
  • 👏 Easier to maintain consistent build vs. runtime environments

Use Cases

  • Compiling code (Go, Node.js, Java, Rust)
  • Installing & optimizing frontend builds (npm run build)
  • Packaging Python apps with pip but leaving out the cache

Multi-stage builds are one of Docker’s most powerful and underutilized features. They help you build production-grade containers that are both efficient and secure. Once you try them, you’ll never go back to bulky images.

You can read more useful articles like Dockerfile Explained: How to Build Custom Docker Images.

Follow us for the more helpful posts!

We hope this is a useful post for you.

5 1 vote
Article Rating
Aaron LX

Aaron LX

Aaron is a passionate writer, crazy about shopping, eCommerce and trends. Besides his outstanding research skills and a positive mind, Aaron eagerly shares his experience with the readers.

Leave a Reply or put your Question here

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x