#!/usr/bin/env bash # Install or update BuildKit as a systemd service, for docker buildx's # remote driver over SSH. From https://exe.dev/deploy/docker-builder. # Run it on the builder VM as exedev. BUILDKIT_VERSION=v0.34.2 pins a release. set -euo pipefail version=${BUILDKIT_VERSION:-latest} if [ "$version" = latest ]; then rel=$(curl -fsSL https://api.github.com/repos/moby/buildkit/releases/latest) else rel=$(curl -fsSL "https://api.github.com/repos/moby/buildkit/releases/tags/$version") fi version=$(jq -r .tag_name <<<"$rel") tarball=buildkit-$version.linux-amd64.tar.gz sha=$(jq -r --arg n "$tarball" '.assets[] | select(.name == $n) | .digest' <<<"$rel") sha=${sha#sha256:} # buildctl, buildkitd, buildkit-runc, the CNI plugins and the QEMU emulators, # into /usr/local/bin, after checking the release's SHA-256. tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT curl -fsSL -o "$tmp/$tarball" "https://github.com/moby/buildkit/releases/download/$version/$tarball" (cd "$tmp" && echo "$sha $tarball" | sha256sum -c --quiet -) sudo tar -C /usr/local -xzf "$tmp/$tarball" # Whoever is in the buildkit group can build. SSH users arrive as exedev. sudo groupadd -f buildkit sudo usermod -aG buildkit exedev # Garbage collection limits. Written once; edit it and restart buildkit. sudo mkdir -p /etc/buildkit if [ ! -e /etc/buildkit/buildkitd.toml ]; then sudo tee /etc/buildkit/buildkitd.toml >/dev/null <<'EOF' # BuildKit on this VM, from https://exe.dev/deploy/docker-builder. # Percentages are of this VM's disk, so they follow a resize. # Reference: https://docs.docker.com/build/cache/garbage-collection/ [worker.oci] enabled = true gc = true # 1. Build contexts and Git checkouts: cheap to send again. [[worker.oci.gcpolicy]] filters = ["type==source.local", "type==source.git.checkout"] keepDuration = "72h" maxUsedSpace = "5%" # 2. RUN --mount=type=cache (Go, npm, pip, cargo...): two weeks unused. [[worker.oci.gcpolicy]] filters = ["type==exec.cachemount"] keepDuration = "336h" maxUsedSpace = "20%" # 3. Anything unused for 30 days, once the cache is over half the disk. [[worker.oci.gcpolicy]] keepDuration = "720h" maxUsedSpace = "50%" # 4. Over the cap, oldest first: at most 60% of the disk, at least 20% free. [[worker.oci.gcpolicy]] reservedSpace = "10%" maxUsedSpace = "60%" minFreeSpace = "20%" [[worker.oci.gcpolicy]] all = true reservedSpace = "10%" maxUsedSpace = "60%" minFreeSpace = "20%" [worker.containerd] enabled = false EOF fi # The socket is /run/buildkit/buildkitd.sock, buildctl's default. sudo tee /etc/systemd/system/buildkit.service >/dev/null <<'EOF' [Unit] Description=BuildKit Documentation=https://github.com/moby/buildkit After=network-online.target Wants=network-online.target [Service] Type=notify ExecStart=/usr/local/bin/buildkitd --addr unix:///run/buildkit/buildkitd.sock --group buildkit Restart=always LimitNOFILE=1048576 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable buildkit.service >/dev/null 2>&1 sudo systemctl restart buildkit.service sudo -u exedev -g buildkit buildctl --addr unix:///run/buildkit/buildkitd.sock debug workers >/dev/null echo "BuildKit $version running on /run/buildkit/buildkitd.sock"