TL;DR — Resumen Rápido
Instala Woodpecker CI para CI/CD autoalojado y ligero. Configura pipelines, secretos, agentes e integración con Gitea, GitHub y GitLab desde cero.
Woodpecker CI es un sistema CI/CD autoalojado y ligero, derivado de Drone CI, que ejecuta pipelines nativos en contenedores con un consumo mínimo de recursos. Esta guía cubre la instalación completa, integración con Gitea, sintaxis de pipelines, gestión de secretos y un pipeline práctico para desplegar una aplicación Go.
Requisitos Previos
- Servidor Linux con Docker y Docker Compose.
- Al menos 512 MB de RAM para servidor + agente (se recomienda 1 GB).
- Una instancia de Gitea, Forgejo, GitHub o GitLab para OAuth.
- Puertos 8000 (HTTP) y 9000 (comunicación gRPC con agentes) abiertos.
Paso 1: Arquitectura de Woodpecker
Woodpecker sigue un modelo servidor + agente:
- Servidor — Gestiona la UI web, API, webhooks y programación de pipelines.
- Agente — Consulta el servidor en busca de trabajo y ejecuta los pasos dentro de contenedores Docker.
- Forge — El proveedor Git (Gitea, GitHub, GitLab) que envía webhooks y autenticación OAuth.
- Pipeline — Definido en
.woodpecker.ymlen la raíz del repositorio.
Paso 2: Instalar con Docker Compose
Crear la App OAuth en Gitea
En Gitea: Ajustes → Aplicaciones → OAuth2 → Crear aplicación OAuth2
- Nombre: Woodpecker CI
- URL de redirección:
http://tu-servidor-woodpecker:8000/authorize
Copia el Client ID y el Client Secret.
Configuración con Docker Compose
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
container_name: woodpecker-server
restart: always
ports:
- "8000:8000"
- "9000:9000"
volumes:
- woodpecker-server-data:/var/lib/woodpecker/
environment:
- WOODPECKER_OPEN=false
- WOODPECKER_HOST=http://tu-servidor:8000
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=http://tu-gitea:3000
- WOODPECKER_GITEA_CLIENT=tu-client-id
- WOODPECKER_GITEA_SECRET=tu-client-secret
- WOODPECKER_AGENT_SECRET=secreto-compartido-fuerte
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
container_name: woodpecker-agent
restart: always
depends_on:
- woodpecker-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=secreto-compartido-fuerte
- WOODPECKER_MAX_PROCS=2
volumes:
woodpecker-server-data:
docker compose up -d
Paso 3: Sintaxis del Pipeline (.woodpecker.yml)
Pipeline Básico
steps:
- name: test
image: golang:1.22
commands:
- go test ./...
- name: build
image: golang:1.22
commands:
- go build -o app .
- name: notificar
image: plugins/slack
settings:
webhook:
from_secret: slack_webhook
when:
- status: [success, failure]
Ejecución Condicional con when
steps:
- name: desplegar
image: alpine
commands:
- ./deploy.sh
when:
- branch: main
event: push
Servicios (Base de Datos, Redis)
services:
- name: postgres
image: postgres:16
environment:
POSTGRES_DB: testdb
POSTGRES_USER: test
POSTGRES_PASSWORD: test
steps:
- name: test
image: golang:1.22
environment:
DATABASE_URL: "postgres://test:test@postgres/testdb?sslmode=disable"
commands:
- go test -tags integration ./...
Matrix Builds
matrix:
GO_VERSION:
- "1.21"
- "1.22"
steps:
- name: test
image: "golang:${GO_VERSION}"
commands:
- go test ./...
Paso 4: Gestión de Secretos
| Ámbito | Configurado por | Visible para |
|---|---|---|
| Repositorio | Propietario del repo | Solo ese repositorio |
| Organización | Admin de la org | Todos los repos de la org |
| Global | Admin del servidor | Todos los repositorios |
Referencia un secreto en el pipeline:
steps:
- name: desplegar
image: alpine
environment:
DEPLOY_KEY:
from_secret: deploy_key
commands:
- echo "$DEPLOY_KEY" | base64 -d > /tmp/key
- ./deploy.sh
Paso 5: Plugins
| Plugin | Imagen | Propósito |
|---|---|---|
| Docker | woodpeckerci/plugin-docker-buildx | Construir y publicar imágenes Docker |
| S3 | woodpeckerci/plugin-s3 | Subir artefactos a S3 |
| Slack | plugins/slack | Notificaciones de build |
| Webhook | woodpeckerci/plugin-webhook | POST a URLs arbitrarias |
Paso 6: Agentes, CLI y Builds Multiplataforma
Etiquetas de Agentes
WOODPECKER_FILTER_LABELS=platform=linux/arm64,type=build
labels:
platform: linux/arm64
steps:
- name: build-arm
image: golang:1.22
commands:
- GOARCH=arm64 go build -o app-arm64 .
woodpecker-cli
export WOODPECKER_SERVER=http://tu-servidor:8000
export WOODPECKER_TOKEN=tu-token-api
woodpecker pipeline ls propietario/repo
woodpecker pipeline start propietario/repo --branch main
woodpecker secret add --repository propietario/repo --name deploy_key --value "$(cat key.pem)"
Tareas Programadas (Cron)
woodpecker cron add --repository propietario/repo --name build-nocturno \
--expr "0 2 * * *" --branch main
Woodpecker vs Alternativas
| Característica | Woodpecker | Drone OSS | Gitea Actions | Jenkins | Concourse |
|---|---|---|---|---|---|
| Licencia | MIT | Apache 2.0 | MIT | MIT | Apache 2.0 |
| RAM (en reposo) | ~50 MB | ~80 MB | ~100 MB | ~500 MB | ~200 MB |
| Formato pipeline | YAML | YAML | YAML (GHA) | Groovy/YAML | YAML |
| Matrix builds | Sí | No (OSS) | Sí | Sí | Sí |
| Multi-pipeline | Sí | No (OSS) | Sí | Sí | No |
| Backend Kubernetes | Sí | Sí | No | Sí | No |
Ejemplo Práctico: Pipeline para Aplicación Go
steps:
- name: test
image: golang:1.22
commands:
- go vet ./...
- go test -race ./...
- name: build-docker
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.ejemplo.com/miapp
tags: ["latest", "${CI_COMMIT_SHA:0:8}"]
platforms: "linux/amd64,linux/arm64"
username:
from_secret: registry_user
password:
from_secret: registry_password
when:
- branch: main
event: push
- name: desplegar
image: alpine
environment:
DEPLOY_KEY:
from_secret: deploy_ssh_key
DEPLOY_HOST:
from_secret: deploy_host
commands:
- apk add --no-cache openssh-client
- echo "$DEPLOY_KEY" | base64 -d > /tmp/key && chmod 600 /tmp/key
- ssh -i /tmp/key -o StrictHostKeyChecking=no deploy@$DEPLOY_HOST
"docker pull registry.ejemplo.com/miapp:latest && docker restart miapp"
when:
- branch: main
event: push
Problemas Comunes
| Problema | Solución |
|---|---|
| Agente no se conecta | Verifica que WOODPECKER_AGENT_SECRET coincida; comprueba que el puerto 9000 esté abierto |
| Pipeline en estado pendiente | Ningún agente conectado o etiquetas no coinciden; revisa el estado del agente en la UI |
| Webhook no se dispara | Verifica que Gitea pueda alcanzar el servidor Woodpecker; revisa Ajustes > Hooks del repo |
| Secretos no inyectados | El nombre del secreto debe coincidir exactamente con el pipeline; revisa el filtro de eventos |
| Build multiplataforma falla | Verifica que QEMU esté instalado o usa privileged: true |
Resumen
- Woodpecker CI es un fork ligero de Drone CI que usa ~50 MB de RAM con arquitectura servidor + agente.
- Se integra con 6 forges (Gitea, Forgejo, GitHub, GitLab, Bitbucket) via OAuth2.
- Los pipelines usan
.woodpecker.ymlcon pasos, servicios, matrix builds y multi-pipeline por rutas. - Los secretos se gestionan por repositorio, organización o globalmente, con backends externos como Vault.
- El CLI
woodpecker-clipermite gestionar pipelines, secretos y tareas cron desde la terminal.