39. Docker Multi-Stage Builds

DOCKER
I’m currently working on a service using Docker, and recently I’ve found something that might be very useful called MULTI-STAGE BUILD so I’d like to share it here.



CONCEPT
For all of my previous works, I’ve been using OPTION 1 from the diagram above. Creating a docker image referring to a requirements.txt file and creating a container from that. However, the size of these containers can become HUGE. That is when Multi-stage build (OPTION 2)comes in handy which helps you drastically reduce the size.

In OPTION 2, you first create a temporary container as a BUILDER with all the requirements installed. An Example of the DockerFile would look like this.

""" BUILDER """

#Create Image as Builder
FROM python:3.9.6-alpine as builder

#Set Environments
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1

#Set directory for this container
WORKDIR /usr/src/back

#Copy requirements.txt to container
COPY ./requirements.txt .

#Cache data to wheel
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/back/wheels -r requirements.txt

Then, you copy from the BUILDER container to the FINAL container which you are going to ultimately use.

""" FINAL """

# Pull official base image
FROM python:3.9.6-alpine

# Copy data from Wheel previously cached
RUN apk update && apk add libpq
COPY --from=builder /usr/src/back/wheels /wheels
COPY --from=builder /usr/src/back/requirements.txt .
RUN pip install --no-cache /wheels/*

EXPERIMENT
I haven’t done this with my actual project yet but I tried doing it with a demo project. The original file size was about 800MB, but by implementing multi-stage build, the size was reduced down to 80MB.

I’m sure that downsizing to 10% of its original size won’t happen in every single project, but I was able to discover the potential of this method.