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