diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 073151d..dc808f0 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -35,25 +35,38 @@ jobs: echo "IMAGE=${REGISTRY_HOST}/${GITHUB_REPOSITORY_OWNER,,}/${{ matrix.image_name }}" >> "$GITHUB_ENV" echo "DATE_TAG=$(date +%Y%m%d)" >> "$GITHUB_ENV" - - name: Build image (uses host Docker via mounted socket) + # Docker's builder cannot handle Bazzite's OSTree base image (millions of + # hardlinks break the containerd snapshotter), so the build runs inside a + # buildah container instead — the same tool Bazzite itself is built with. + - name: Build and push with buildah run: | - docker build \ - -f Containerfile \ - --build-arg BASE_IMAGE="${{ matrix.base_image }}" \ - --build-arg BASE_TAG=stable \ - -t "${IMAGE}:stable" \ - -t "${IMAGE}:latest" \ - -t "${IMAGE}:${DATE_TAG}" \ - . + docker volume create kamos-buildah-cache >/dev/null 2>&1 || true + tar -cf - . | docker run --rm -i --privileged \ + -v kamos-buildah-cache:/var/lib/containers \ + -e IMAGE="${IMAGE}" \ + -e DATE_TAG="${DATE_TAG}" \ + -e BASE_IMAGE="${{ matrix.base_image }}" \ + -e RUSER="${{ secrets.REGISTRY_USER }}" \ + -e RTOKEN="${{ secrets.REGISTRY_TOKEN }}" \ + quay.io/buildah/stable:latest \ + bash -c ' + set -euo pipefail + mkdir -p /src && tar -xf - -C /src && cd /src + buildah build -f Containerfile \ + --build-arg BASE_IMAGE="$BASE_IMAGE" \ + --build-arg BASE_TAG=stable \ + -t "$IMAGE:stable" . + buildah tag "$IMAGE:stable" "$IMAGE:latest" "$IMAGE:$DATE_TAG" + for tag in stable latest "$DATE_TAG"; do + buildah push --creds "$RUSER:$RTOKEN" "$IMAGE:$tag" "docker://$IMAGE:$tag" + done + ' - - name: Push to Forgejo container registry - run: | - echo "${{ secrets.REGISTRY_TOKEN }}" | \ - docker login "${REGISTRY_HOST}" -u "${{ secrets.REGISTRY_USER }}" --password-stdin - for tag in stable latest "${DATE_TAG}"; do - docker push "${IMAGE}:${tag}" - done - - - name: Clean up build cache (keep server disk healthy) + - name: Clean up (keep server disk healthy) if: always() - run: docker image prune -f + run: | + # The failed docker-builder attempts left ~40 GB of unusable Bazzite + # layers in Docker's store — reclaim them; buildah has its own cache. + docker rmi ghcr.io/ublue-os/bazzite:stable ghcr.io/ublue-os/bazzite-nvidia:stable 2>/dev/null || true + docker image prune -f + docker builder prune -af || true