This Dockerfile allow to bootstrap a pristine, minimal and optimized gentoo image. It fetches the latest stage3 tarball, portage and recompiles the whole system using GCC -march=native -Os
optimizations.
Recompilinig the whole system twice takes quite some time (~4h on my MacBook Pro using 8 threads: MAKEOPTS="-j8"
), so it might not be what you want.
If you have compatible hardware, you can fetch a ready to use image from my Docker Hub repo: https://cloud.docker.com/u/gfrancesco11/repository/docker/gfrancesco11/gentoo-stage4
Images on the Docker Hub have been compiled for an Intel i9-8950HK CPU, using these GCC -march=native -Os
optimizations.
Some parts of the Dockerfile come from the official Gentoo dockerfile gentoo/gentoo-docker-images.
I tested the Dockerfile using Docker Desktop v2.1.0.3 for MacOS, with Docker Engine v19.03.2, YMMV.
Requirements:
- You need to enable Experimental features in the docker daemon, since the Dockerfile needs to be built using
buildx
that extends the docker command with the full support of the features provided by Moby BuildKit builder toolkit. - The number of CPUs you allocate do the Docker daemon should be greater than the number of threads you use in GCC to emerge and compile the gentoo packages, otherwise compilation will fail. By default the Dockerfile uses 8 threads, but you can change this number at build time.
- Some of the compilation is performed in RAM, I allocated 10 GiB to my Docker daemon, but it might work with less.
-
Create the Buildkit builder
docker buildx create --use --name insecure-builder --buildkitd-flags '--allow-insecure-entitlement security.insecure'
-
Choose your build-time customization options:
-
--build-arg SUFFIX="-nomultilib"
see gentoo/gentoo-docker-images for the full list of options, I only tested-nomultilib
withARCH=amd64
(which is the default ARCH). -
--build-arg CPU_N=4
number of threads used by GCC to compile the packages, the default is8
. -
--cache-to=type=local,dest=gentoo_cache
saves the build cache into thegentoo_cache
folder. -
--cache-from=type=local,src=gentoo_cache
fetches the build cache from thegentoo_cache
folder, remove this option on your first build, since you'll have no cache from previous builds.
-
-
Build the image:
docker buildx build \
--build-arg SUFFIX="-nomultilib" \
--build-arg CPU_N=4 \
--allow security.insecure \
--cache-to=type=local,dest=gentoo_cache \
--cache-from=type=local,src=gentoo_cache \
--load -t your_user/gentoo-stage4:"$(date -u +%Y%m%d)" \
-f gentoo-stage4.Dockerfile .
The final image is size-optimized, a -nomultilib
build is less than 900 MiB and does not include the portage tree.
To run the container in interactive mode you can use:
docker run -t -i --cap-add=SYS_ADMIN --cap-add=NET_ADMIN --cap-add=SYS_PTRACE --rm your_user/gentoo-stage4
The --cap-add
statements are required to prevent permission errors/warnings when emerging packages and to be able to emerge some packages like sys-libs/glibc, which will otherwise fail to compile. If your application runs without errors/warnings you can remove them.
If you need the portage tree in your container you can mount it as a volume from the official gentoo/portage
image:
docker create --name portage_c gentoo/portage
docker run -t -i --rm --volumes-from portage_c your_user/gentoo-stage4:latest
1. What's the difference between this project and the official gentoo/gentoo-docker-images?
- The official gentoo/gentoo-docker-images use a wrapper build script, while I preferred to avoid additional code outside the Dockerfile. The
gentoo-stage4
images are pre-configured and entirely recompiled with GCC optimizations, that is possible thanks to BuildKit.