Replaces the third-party catthehacker/ubuntu:runner-latest image with our own git.librete.ch/libretech/runner-image:v1 (Ubuntu 24.04 + docker CLI + node + git + perl, runner uid 1001 in docker gid 998 — no --user root needed).
deploy.yml collapses build + deploy into a single job. Tag computation moved to docker/metadata-action@v5.
Removes the per-deploy perl -i rewrite of LIBRENOTES_IMAGE on the host. The host pins it once in /srv/librenotes/.env and main pushes update the rolling :main tag; rollback / release pinning is a manual .env edit + compose pull && up -d (documented in docs/operations.md).
Drops the unused generic compose.prod.yaml overlay.
ci.yml moves to the same image so make, git, node, go-via-setup-go all work without per-step apt installs.
Why
Two regressions on the previous workflow caught only at runtime:
Workflow-level volumes: /var/run/docker.sock:/var/run/docker.sock collided with act_runner's own auto-mount → Duplicate mount point failure.
The third-party image's runner user (uid 1001) wasn't in the host's docker group, so even after fixing #1 the build failed with permission denied while trying to connect to the docker API.
The bespoke image bakes the group membership in (build-arg DOCKER_GID=998, matches netcup), and the workflow no longer adds a duplicate mount, so both invariants are codified rather than retried.
Verification
yq -e . parses both workflow YAMLs.
docker compose -f compose.yaml -f compose.netcup.yaml config resolves with the new image ref.
Local docker run --rm -v /var/run/docker.sock:/var/run/docker.sock --group-add 131 git.librete.ch/libretech/runner-image:v1 bash -c 'id; docker version; node -v; git --version; make -v | head -1' returns uid=1001 (not root) and lists all required tools.
Out of scope (already in flight elsewhere)
Self-hosting CI for the runner-image repo: shipped as git.librete.ch/libretech/runner-image:.gitea/workflows/build.yml.
Server update / security audit on netcup itself.
Cleanup follow-up to #42.
## Summary
- Replaces the third-party `catthehacker/ubuntu:runner-latest` image with our own `git.librete.ch/libretech/runner-image:v1` (Ubuntu 24.04 + docker CLI + node + git + perl, runner uid 1001 in docker gid 998 — no `--user root` needed).
- `deploy.yml` collapses `build` + `deploy` into a single job. Tag computation moved to `docker/metadata-action@v5`.
- Removes the per-deploy `perl -i` rewrite of `LIBRENOTES_IMAGE` on the host. The host pins it once in `/srv/librenotes/.env` and main pushes update the rolling `:main` tag; rollback / release pinning is a manual `.env` edit + `compose pull && up -d` (documented in `docs/operations.md`).
- Drops the unused generic `compose.prod.yaml` overlay.
- `ci.yml` moves to the same image so `make`, `git`, `node`, `go-via-setup-go` all work without per-step apt installs.
## Why
Two regressions on the previous workflow caught only at runtime:
1. Workflow-level `volumes: /var/run/docker.sock:/var/run/docker.sock` collided with act_runner's own auto-mount → `Duplicate mount point` failure.
2. The third-party image's `runner` user (uid 1001) wasn't in the host's docker group, so even after fixing #1 the build failed with `permission denied while trying to connect to the docker API`.
The bespoke image bakes the group membership in (build-arg `DOCKER_GID=998`, matches netcup), and the workflow no longer adds a duplicate mount, so both invariants are codified rather than retried.
## Verification
- `yq -e .` parses both workflow YAMLs.
- `docker compose -f compose.yaml -f compose.netcup.yaml config` resolves with the new image ref.
- Local `docker run --rm -v /var/run/docker.sock:/var/run/docker.sock --group-add 131 git.librete.ch/libretech/runner-image:v1 bash -c 'id; docker version; node -v; git --version; make -v | head -1'` returns uid=1001 (not root) and lists all required tools.
## Out of scope (already in flight elsewhere)
- Self-hosting CI for the runner-image repo: shipped as `git.librete.ch/libretech/runner-image:.gitea/workflows/build.yml`.
- Server update / security audit on netcup itself.
The deploy workflow is now a single job that builds, pushes, and
deploys in one runner. Tag computation moved to docker/metadata-action,
the per-deploy .env perl rewrite is gone (host pins LIBRENOTES_IMAGE
once; main pushes update :main rolling, releases pin to :vX.Y.Z by
manual edit), and both jobs run in our bespoke runner image whose
runner user already has socket access via group membership.
ci.yml moves to the same image so go/make/node are all available
without per-step apt installs.
Drops compose.prod.yaml (unused, redundant with compose.netcup.yaml).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Cleanup follow-up to #42.
Summary
catthehacker/ubuntu:runner-latestimage with our owngit.librete.ch/libretech/runner-image:v1(Ubuntu 24.04 + docker CLI + node + git + perl, runner uid 1001 in docker gid 998 — no--user rootneeded).deploy.ymlcollapsesbuild+deployinto a single job. Tag computation moved todocker/metadata-action@v5.perl -irewrite ofLIBRENOTES_IMAGEon the host. The host pins it once in/srv/librenotes/.envand main pushes update the rolling:maintag; rollback / release pinning is a manual.envedit +compose pull && up -d(documented indocs/operations.md).compose.prod.yamloverlay.ci.ymlmoves to the same image somake,git,node,go-via-setup-goall work without per-step apt installs.Why
Two regressions on the previous workflow caught only at runtime:
volumes: /var/run/docker.sock:/var/run/docker.sockcollided with act_runner's own auto-mount →Duplicate mount pointfailure.runneruser (uid 1001) wasn't in the host's docker group, so even after fixing #1 the build failed withpermission denied while trying to connect to the docker API.The bespoke image bakes the group membership in (build-arg
DOCKER_GID=998, matches netcup), and the workflow no longer adds a duplicate mount, so both invariants are codified rather than retried.Verification
yq -e .parses both workflow YAMLs.docker compose -f compose.yaml -f compose.netcup.yaml configresolves with the new image ref.docker run --rm -v /var/run/docker.sock:/var/run/docker.sock --group-add 131 git.librete.ch/libretech/runner-image:v1 bash -c 'id; docker version; node -v; git --version; make -v | head -1'returns uid=1001 (not root) and lists all required tools.Out of scope (already in flight elsewhere)
git.librete.ch/libretech/runner-image:.gitea/workflows/build.yml.