Skip to content

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-server publishes gRPC on 127.0.0.1:9000 (Docker ports).
  • Systemd unit woodpecker-grpc-tunnel on infra: -R 127.0.0.1:9000:127.0.0.1:9000 to apps.
  • Apps agent uses network_mode: host and WOODPECKER_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.sh
  • scripts/setup-woodpecker-grpc-tunnel.sh
  • scripts/allow-apps-vps-woodpecker-grpc.sh (UFW on infra if raw 9000 is opened later)

Verification

  1. Woodpecker UI → Settings → Agents — both infra-vps and apps-vps connected.
  2. Push infra/devops → builds only on infra (docker ps during pipeline on infra VPS).
  3. Push alex/wearlab-main → build steps on apps VPS; deploy SSH still targets 82.165.177.110.
  4. 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_SECRET on server and both agents (from SOPS / vps-stack.env).
  • ci-grpc Traefik router uses IP allowlist middleware (82.165.177.110/32 only).
  • UFW rule for apps IP → 9000 on infra is optional (tunnel uses SSH 22).
  • Do not expose Woodpecker gRPC on 0.0.0.0:9000 without IP restriction.