Woodpecker agents¶
Woodpecker server + UI run on the infra VPS (ci.rafaelgonzalezalbes.com). Builds are split across two agents using workflow labels and agent WOODPECKER_AGENT_LABELS.
Layout¶
flowchart LR
Dev[Developer push] --> UI[ci.rafaelgonzalezalbes.com]
UI --> Server[woodpecker-server on infra VPS]
Server -->|gRPC| InfraAgent[infra-vps agent MAX 1]
Server -->|gRPC tunnel| AppsAgent[apps-vps agent MAX 2]
InfraAgent --> InfraBuild[infra/devops platform deploy]
AppsAgent --> AppBuild[Kaniko npm docker builds]
AppsAgent -->|SSH deploy| AppsStacks[/opt/apps/*]
| Component | Host | Agent hostname | Labels | Max workflows |
|---|---|---|---|---|
woodpecker-server + DB |
Infra 85.215.32.166 |
— | — | — |
woodpecker-agent |
Infra | infra-vps |
!location=infra-vps, location=infra-vps, repo=* |
1 |
woodpecker-agent-apps |
Apps 82.165.177.110 |
apps-vps |
!location=apps-vps, location=apps-vps, repo=* |
2 |
The !location=… prefix is mandatory — pipelines without a matching labels: block will not run on any agent.
Pipeline labels¶
Add top-level labels in each repo’s .woodpecker.yml:
| Repo | Label |
|---|---|
infra/devops |
location: infra-vps |
rafael.gonzalez.albes/portfolio |
location: infra-vps |
alex/wearlab-main |
location: apps-vps |
Templates: templates/woodpecker-static-sftp.yml, templates/woodpecker-frontend-backend.yml.
Remote agent connectivity (apps VPS)¶
IONOS does not allow raw TCP 9000 between VPSes (only 22/80/443). Options:
1. Reverse SSH tunnel (default, no extra DNS)¶
Infra VPS opens a reverse tunnel to apps VPS so gRPC is available on apps 127.0.0.1:9000:
bash scripts/setup-woodpecker-grpc-tunnel.sh # systemd on infra
bash scripts/deploy-apps-woodpecker-agent.sh # agent on apps (tunnel mode)
- Infra
woodpecker-serverpublishes gRPC on127.0.0.1:9000(Dockerports). - Systemd unit
woodpecker-grpc-tunnelon infra:-R 127.0.0.1:9000:127.0.0.1:9000to apps. - Apps agent uses
network_mode: hostandWOODPECKER_SERVER=127.0.0.1:9000(tunnel is localhost-only).
2. Traefik ci-grpc subdomain (optional upgrade)¶
Add DNS A record: ci-grpc.rafaelgonzalezalbes.com → infra VPS IP.
Traefik routes that host to Woodpecker gRPC (h2c on port 9000). Deploy apps agent in traefik mode:
WOODPECKER_GRPC_MODE=traefik bash scripts/deploy-apps-woodpecker-agent.sh
Env: WOODPECKER_SERVER=ci-grpc.rafaelgonzalezalbes.com:443, WOODPECKER_GRPC_SECURE=true, WOODPECKER_GRPC_VERIFY=true.
Deploy paths¶
| Path | Purpose |
|---|---|
/opt/devops |
Infra stack (docker-compose.yml) |
/opt/apps/woodpecker-agent |
Apps agent compose + .env |
Scripts:
scripts/deploy-apps-woodpecker-agent.shscripts/setup-woodpecker-grpc-tunnel.shscripts/allow-apps-vps-woodpecker-grpc.sh(UFW on infra if raw 9000 is opened later)
Verification¶
- Woodpecker UI → Settings → Agents — both
infra-vpsandapps-vpsconnected. - Push
infra/devops→ builds only on infra (docker psduring pipeline on infra VPS). - Push
alex/wearlab-main→ build steps on apps VPS; deploy SSH still targets82.165.177.110. - Pipeline stuck waiting for agent → missing or wrong
labels:in.woodpecker.yml.
Troubleshooting¶
| Symptom | Check |
|---|---|
Apps agent 404 on ci.*:443 |
gRPC cannot share the UI host without ci-grpc DNS; use tunnel mode. |
Apps agent DeadlineExceeded |
Tunnel down: systemctl status woodpecker-grpc-tunnel on infra; nc -zv 127.0.0.1 9000 on apps. |
Infra agent connection refused |
woodpecker-server unhealthy — check DB password vs /run/infra-secrets/vps-stack.env. |
| No agent picks job | Add labels: location: … matching an agent; redeploy agent labels. |
| Kaniko / buildx fails | Server WOODPECKER_PLUGINS_PRIVILEGED includes woodpeckerci/plugin-kaniko and docker-buildx. |
Security notes¶
- Agent secret: same
WOODPECKER_AGENT_SECRETon server and both agents (from SOPS /vps-stack.env). ci-grpcTraefik router uses IP allowlist middleware (82.165.177.110/32only).- UFW rule for apps IP → 9000 on infra is optional (tunnel uses SSH 22).
- Do not expose Woodpecker gRPC on
0.0.0.0:9000without IP restriction.