Docker has become an integral part of modern software development and deployment workflows. One of the challenges developers often face is creating lean and efficient Docker images. This is where Docker Multi-Stage Builds come into play, offering a powerful solution to streamline the image-building process.
What is Docker Multi-Stage Build?
Docker Multi-Stage Build is a feature introduced to help developers create smaller and more secure Docker images. It allows you to use multiple FROM statements in your Dockerfile, creating a series of build stages. Each stage can have its own set of instructions, dependencies, and build context.
The primary goal of Multi-Stage Builds is to separate the build environment from the runtime environment. This separation is crucial for minimizing the size of the final Docker image and reducing its attack surface.
Why is it Necessary?
1. Reduced Image Size:
Multi-Stage Builds enable you to discard unnecessary build artifacts in the final image, resulting in smaller and more efficient images. This is particularly important for microservices architectures and cloud-native applications where image size directly impacts deployment speed and resource utilization.
2. Security:
By separating the build and runtime environments, you minimize the potential vulnerabilities in the final image. The final image only contains the necessary runtime dependencies, reducing the attack surface and making it more secure.
3. Build Optimization:
Multi-Stage Builds allow you to optimize the build process by leveraging intermediate images. This can lead to faster builds and more efficient use of resources during the development and deployment workflows.
Demonstration of Docker mulit stage file:
The following file is a simple docker file :
FROM python:3.9
WORKDIR /app
COPY backend/ /app
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]
We will build this image first by following command which is:
- docker build -t python-multistage .
Run this image to form a running container:
- docker run -d -p 8001:8001 python-multistage:latest
We have successfully build a container for the python-multistage image
But when we do "docker images", we can see the size of image which is show below:
How to reduce the image size ?
The simple answer would be to build a docker multistage build file which will our image file to reduce drastically.
We can reuse the above FROM base image in a lighter or less base image size which are available on internet. for an example if we are taking an base image of "python:3.9" instead we can use more lighter image which is also called as "python:3.9-slim-buster".
Additionally we can use "--no-cache-dir" what this usually does it stops creating the cache files each time your create or build image which can also save more space to it.
We will build the multi stage build file in the following way:
# Stage 1: Build the Flask Application
FROM python:3.9 AS backend-builder
WORKDIR /app
COPY backend/requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY backend/ .
# Stage 2: Final Image
FROM python:3.9-slim-buster
WORKDIR /app
COPY --from=backend-builder /app /app
EXPOSE 5000
CMD ["python", "app.py"]
after creating this docker multistage build file we will actually build this file into image. As we have created the simple docker file image which costed around 1.01 GB of our space.
Let's see MAGIC after creating the new image:
It will decrease in the size significantly that's the power of docker multistage build.
Conclusion:
Docker Multi-Stage Builds offer a powerful way to create efficient and secure Docker images. By separating the build and runtime environments, developers can significantly reduce image size, enhance security, and optimize the build process.
Code like no one is watching, debug like everyone is ๐