Replaces the per-project deploy scripts and self-contained webhook receivers with one manifest-driven implementation that lives outside the application repositories and can be updated independently of them. First targets: domaindingo test and prod on s5.
3.6 KiB
Rootless Docker Gitea Runner Notes
Reusable setup for running Gitea Actions jobs on a rootless Docker host when
jobs need Docker access (Playwright, Buildx). The runner runs as a container;
job containers reach the host's rootless socket. Substitute the rootless socket
path /run/user/<UID>/docker.sock for your runner user (examples use 3100).
Runner compose
Mount the rootless socket into the runner container:
services:
gitea-runner-1:
image: gitea/act_runner:latest
container_name: s4-runner-1
restart: unless-stopped
environment:
GITEA_INSTANCE_URL: https://gitea.example.com
GITEA_RUNNER_REGISTRATION_TOKEN: ${GITEA_RUNNER_REGISTRATION_TOKEN}
GITEA_RUNNER_NAME: s4-runner-1
CONFIG_FILE: /data/config.yaml
volumes:
- runner1_data:/data
- ./config.yaml:/data/config.yaml:ro
- /run/user/3100/docker.sock:/var/run/docker.sock
volumes:
runner1_data:
Runner config
container:
docker_host: "-" # critical
options: "-v /run/user/3100/docker.sock:/var/run/docker.sock"
valid_volumes:
- /run/user/3100/docker.sock # source path only
docker_host: "-" stops act_runner from adding its own socket mount on top of
the one in options, which otherwise fails job creation with
Duplicate mount point: /var/run/docker.sock. Keep valid_volumes as the host
source path only (not the src:dst bind form).
Workflow patterns
- Buildx: use
docker/setup-buildx-action@v3withdriver: docker. The default driver starts a separate BuildKit container that misbehaves on this runner shape; thedockerdriver uses the mounted daemon directly. - No setup-node cache: drop
cache: pnpmfromactions/setup-node@v4; the job network often can't reach the Gitea Actions cache service (minutes of restore/save timeouts). Usepnpm install --frozen-lockfileinstead. Revisit only once the cache-service network path is confirmed. - Playwright: split browser E2E from validation — build + upload artifact in
a normal job, then run Playwright in the official image
(
mcr.microsoft.com/playwright:v1.58.2-noble) against the downloaded artifact.
Host checks
docker context show; echo "$DOCKER_HOST"; ls -l /run/user/3100/docker.sock; docker info
# DOCKER_HOST should be unix:///run/user/3100/docker.sock
docker run --rm -v /run/user/3100/docker.sock:/var/run/docker.sock docker:27-cli docker version
If that container can't use the socket, fix rootless Docker before touching the runner.
Troubleshooting
Duplicate mount point: /var/run/docker.sock— setdocker_host: "-", keep the bind only inoptions,valid_volumes= source path only, recreate.WARNING: IPv4 forwarding is disabledmay persist even after hostnet.ipv4.ip_forward=1.systemctl --user restart dockerand re-checkdocker info. If jobs create containers and reach their networks, treat it as stale output, not a failure.- Buildx/build fails — use
driver: docker; confirmdocker versionworks through the mounted socket.
Useful commands
docker ps --format '{{.ID}} {{.Image}} {{.Status}} {{.Names}}'
docker logs --tail 120 s4-runner-1
docker compose up -d --force-recreate gitea-runner-1
tea actions runs --repo owner/repo
tea actions runs logs <run-id> --job <job-id> --repo owner/repo
Known-good (Grindex / current runner)
Host s4.fisher.hu; container s4-runner-1; image gitea/act_runner:latest;
socket /run/user/3100/docker.sock; workflows in .gitea/workflows; Buildx
driver: docker; setup-node cache disabled.