diff --git a/Dockerfile b/Dockerfile index 48fa2ae..e6119e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ # syntax=docker/dockerfile:1.10.0@sha256:865e5dd094beca432e8c0a1d5e1c465db5f998dca4e439981029b3b81fb39ed5 FROM ksmanis/stage3:20240930@sha256:8e8a7c86ab167ea0b740664492e78dc97c33cc59f6fff13bf4ac40bca7804a37 AS distcc-builder +ARG CCACHE_DIR=/var/cache/ccache +ENV CCACHE_DIR=$CCACHE_DIR RUN --mount=type=bind,from=ksmanis/gentoo-distcc:tcp,source=/var/cache/binpkgs,target=/cache \ --mount=type=bind,from=ksmanis/portage,source=/var/db/repos/gentoo,target=/var/db/repos/gentoo \ set -eux; \ @@ -8,10 +10,18 @@ RUN --mount=type=bind,from=ksmanis/gentoo-distcc:tcp,source=/var/cache/binpkgs,t emerge --info; \ emerge distcc; \ distcc --version; \ + emerge ccache; \ + ccache --version; \ + echo "CCACHE_DIR=${CCACHE_DIR}" > /etc/env.d/02distcc-ssh-ccache; \ + env-update; \ + mkdir "${CCACHE_DIR}"; \ + chmod 0775 "${CCACHE_DIR}"; \ + chown distcc:distcc "${CCACHE_DIR}"; \ emerge --oneshot gentoolkit; \ eclean packages; \ CLEAN_DELAY=0 emerge --depclean gentoolkit; \ find /var/cache/distfiles/ -mindepth 1 -delete -print +VOLUME $CCACHE_DIR FROM distcc-builder AS distcc-tcp ARG TARGETPLATFORM diff --git a/README.md b/README.md index 2f064c4..eeb4e1c 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,63 @@ through the optional `SSH_USERNAME` environment variable: docker run -d -p 30022:22 -e SSH_USERNAME=bob -e AUTHORIZED_KEYS="..." --name gentoo-distcc-ssh --rm ksmanis/gentoo-distcc:ssh ``` +### Persistent [ccache(1)](https://ccache.dev/manual/latest.html) + +Ccache speeds up recompilation by caching the result of previous compilations +and detecting when the same compilation is being done again. That can help save +time on compilation if you end up recompiling for any reason i.e. because you +have multiple gentoo machines which have an overlapping package selection. + +Check the [gentoo wiki](https://wiki.gentoo.org/wiki/Ccache) to learn more. If +you only have one gentoo machine and it has enough disk space to host its own +cache, you might be better off with one local ccache on that machine with +`FEATURES="ccache"`. If you want to also add a cache to the container, keep +reading. + +To enable the use of `ccache` you have to set `DISTCC_CCACHE_ENABLE` to `1`. And +to further make it persist over multiple container runs you need to mount a +container volume or a host directory to `/var/cache/ccache`. + +#### Example with a persistent ccache in a docker volume + +Create a new volume for persistency: + +```shell +docker volume create gentoo-distcc-ccache +``` + +```shell +docker run -d -p 3632:3632 --name gentoo-distcc-tcp --rm -v gentoo-distcc-ccache:/var/cache/ccache/:rw -e DISTCC_CCACHE_ENABLE=1 ksmanis/gentoo-distcc:tcp +``` + +For the ssh variant of the container images it works exactly the same way. + +#### Notes on ccache + +To check the status of the cache you can run `ccache -s` with the container +image like that: + +```shell +docker run -t -i --rm -v gentoo-distcc-ccache:/var/cache/ccache/:rw ksmanis/gentoo-distcc:tcp watch -d ccache -s +``` + +In case you created a container with the ssh variant, you can also ssh into it +and run `ccache -s`. + +```shell +ssh localhost-distcc ccache -s +``` + +You should see the cache filling up and if you compile the same package twice +you should see cache hits coming in. If you are using `FEATURES="ccache"` from +gentoo you might want to disable it for a test. Otherwise local cache hits will +prevent remote compilation. + +When you choose a bind-mount the cache is a shared folder between the host and +the container. If both want to access it you might have to play with `chown` and +`CCACHE_UMASK` (or `umask` in ccache.conf). Note that a world writable cache +will have security implications on all systems using distcc. + ## Testing A manual way to test the containers is to compile a sample C file: diff --git a/docker-entrypoint-ssh.sh b/docker-entrypoint-ssh.sh index 785e573..e4bdb6a 100755 --- a/docker-entrypoint-ssh.sh +++ b/docker-entrypoint-ssh.sh @@ -26,6 +26,10 @@ if [ "$1" = "sshd" ]; then fi # Execute sshd using absolute path shift + if [ "${DISTCC_CCACHE_ENABLE}" = 1 ]; then + echo "PATH=/usr/lib/ccache/bin" >> /etc/env.d/02distcc-ssh-ccache + env-update + fi exec /usr/sbin/sshd "$@" fi diff --git a/docker-entrypoint-tcp.sh b/docker-entrypoint-tcp.sh index a70d5a7..1433c4b 100755 --- a/docker-entrypoint-tcp.sh +++ b/docker-entrypoint-tcp.sh @@ -6,6 +6,9 @@ set -e # * if hyphenated flag arguments (e.g., '-f', '-foo', or '--foo') were # passed to the Docker command line if [ "$#" -eq 0 ] || [ "${1#-}" != "$1" ]; then + if [ "${DISTCC_CCACHE_ENABLE}" = 1 ]; then + export PATH="/usr/lib/ccache/bin:$PATH" + fi exec distccd --daemon --no-detach --log-level notice --log-stderr --allow-private "$@" fi