From a6592d3ad03c1f9c48bd45a1ae83f418b086f1e1 Mon Sep 17 00:00:00 2001 From: Phil Date: Sat, 31 Oct 2026 11:53:59 -0600 Subject: [PATCH] Take the Docker socket away from the Gitea runner Jobs run inside the runner container (label docker:host), and with the host's Docker socket mounted every workflow had root on the server. The socket was only there for StarPunk's image build, which has never worked (it logged in to gitea:3000, which the host daemon can't resolve). Image builds now go to a rootless BuildKit container that shares only a unix socket with the runner. Site builds keep their /sites mount. Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 2 +- roles/docker/README.md | 2 +- roles/docker/templates/gitea-compose.yml.j2 | 24 ++++++++++++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7d400ba..1a74bb4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -82,7 +82,7 @@ subdomain. ### Docker role categories (`roles/docker/tasks//`) - **infrastructure/**: Caddy, Pocket ID, Dockge -- **development/**: Gitea (+ act_runner), ByteStash +- **development/**: Gitea (+ act_runner and rootless BuildKit; the runner has no Docker socket), ByteStash - **media/**: Audiobookshelf, Kavita, Karakeep (files named `hoarder`), Manyfold - **productivity/**: Paperless-ngx, Baikal, Syncthing, HeyForm, Dawarich, Obsidian LiveSync, Gokapi - **communication/**: GoToSocial, Listmonk, StarPunk (Micropub) diff --git a/roles/docker/README.md b/roles/docker/README.md index 0b2fe01..66f98bd 100644 --- a/roles/docker/README.md +++ b/roles/docker/README.md @@ -31,7 +31,7 @@ Tags: each category file has a category tag, each service its own tag. ### Development (`development`) | Tag | Service | Notes | |---|---|---| -| `gitea` | Gitea + act_runner | Fixed IP 172.20.0.6 so the ufw-docker rule for SSH (host port 222) stays valid. Pocket ID login is set up in Gitea's admin UI; OpenID 2.0 login is off. | +| `gitea` | Gitea + act_runner + BuildKit | Fixed IP 172.20.0.6 so the ufw-docker rule for SSH (host port 222) stays valid. Pocket ID login is set up in Gitea's admin UI; OpenID 2.0 login is off. Jobs run inside the runner container (label `docker:host`), which has the Caddy site folders at `/sites` but no Docker socket. Image builds use the rootless `buildkitd` container through `unix:///run/buildkit/buildkit/buildkitd.sock` (`docker buildx create --driver remote`). | | `bytestash` | ByteStash | Pocket ID through env vars. | ### Media (`media`) diff --git a/roles/docker/templates/gitea-compose.yml.j2 b/roles/docker/templates/gitea-compose.yml.j2 index b42adfe..db4e91f 100644 --- a/roles/docker/templates/gitea-compose.yml.j2 +++ b/roles/docker/templates/gitea-compose.yml.j2 @@ -51,11 +51,33 @@ services: volumes: - ./runner-config.yaml:/config.yaml - ./data:/data - - /var/run/docker.sock:/var/run/docker.sock + # No Docker socket: jobs run inside this container (label docker:host), + # and the socket would give every workflow root on the server. + # Image builds go to the rootless BuildKit below through its socket at + # /run/buildkit/buildkit/buildkitd.sock. + - buildkit-run:/run/buildkit - {{ paths.stacks }}/caddy/site:/sites + buildkitd: + image: moby/buildkit:rootless + restart: unless-stopped + # Rootless BuildKit in an unprivileged container (see BuildKit's + # docs/rootless.md). It listens only on a unix socket shared with the runner. + command: ["--oci-worker-no-process-sandbox"] + security_opt: + - seccomp=unconfined + - apparmor=unconfined + extra_hosts: + - '{{ subdomains.git }}:{{ docker.hairpin_ip }}' + labels: + mag37.dockcheck.update: true + volumes: + - buildkit-run:/run/user/1000 + - buildkit-cache:/home/user/.local/share/buildkit volumes: gitea: driver: local + buildkit-run: + buildkit-cache: networks: default: external: true