User:Arzano/Towards a slim Gentoo container image
This page describes how to get slim Gentoo based container images.
Current Image
Currently gentoo/stage3-amd64 is used as base image. Furthermore, gentoo/portage is used to copy the full ebuild tree into the container. This way it is possible to install packages.
Consequently, a typical Dockerfile currently looks like this:
Dockerfile
FROM gentoo/portage:latest as portage # Used as base image FROM gentoo/stage3-amd64 # Need a portage tree to build packages COPY --from=gentoo/portage:latest /var/db/repos/gentoo /var/db/repos/gentoo # Install packages that are needed to build AND run the application RUN emerge ... # Copy the application COPY ./ /var/www/packages.gentoo.org/htdocs/ # Build the application RUN ... # Run the application CMD ...
Where this falls short
Unfortunately this results in rather large images, as
- the image contains dependencies that are only needed during the build and not needed at runtime, and
- the image contains dependencies that are neither needed during build nor at runtime (as they are included in the stage3 base image)
New Image
To solve the problems of the current approach:
- a multi stage build is used to exclude the dependencies that are only needed during the build
- a slim Stage 1 base image is used to exclude dependencies that are neither needed during build nor at runtime
Multi Stage Build
A multi stage build is used to build the application / static contents and copy only the required artifacts into the image. The multistage Dockerfile looks like this:
Dockerfile
# ------------------- builder stage FROM gentoo/stage3-amd64 as builder # Need a portage tree to build packages COPY --from=gentoo/portage:latest /var/db/repos/gentoo /var/db/repos/gentoo # Install packages that are needed to build the application RUN emerge ... # Copy the application COPY ./ /var/www/packages.gentoo.org/htdocs/ # Build the application RUN ... # ------------------- production stage # Use a slim base image FROM gentoo/stage1-amd64-ruby # Copy the application COPY ./ /var/www/packages.gentoo.org/htdocs/ # Copy the required artifacts from the last stage into the image COPY --from=builder ... # Run the application CMD ...
Stage 1 image
Catalyst can be used to create a stage1 tarball. The linux/amd64/17.1 profile will be modified to:
- exclude as many non-essential packages as possible, and
- add further packages which are needed at runtime (as ruby for instance)
Afterwards the Stage 1 image can be created the same way as the Stage 3 image is currently created. [1] This way, a slim base image is created.
Creating the image during builder stage
The stage 1 image including all runtime dependencies can be created during the builder stage like this:
Dockerfile
# ------------------- builder stage FROM gentoo/stage3-amd64 as builder # ... # Specifiy all needed runtime dependencies, for instance redis or ruby or python RUN ... # Build the minimal stage 1 image including all runtime dependencies using Catalyst or the like RUN ... # Extract the created stage 1 tarball to /gentoo RUN ... # ------------------- production stage FROM scratch # Use the minimal stage 1 including all runtime dependencies created before COPY --from=builder /gentoo / #...
Comparison
As for the packages.g.o image, it turns out that the new image is 15 times smaller than the current image:
Current Image: | 3000mb |
New Image: | 200mb |