Instalación y Configuración de Woodpecker CI
Woodpecker CI es un sistema de integración continua ligero y nativo de contenedores, diseñado para funcionar directamente con Gitea y Forgejo como fuente de repositorios. Con una arquitectura de servidor y agentes distribuidos, pipelines definidos en YAML y soporte para múltiples plataformas, Woodpecker es una alternativa autoalojada ideal a servicios como GitHub Actions o CircleCI.
Requisitos Previos
- Servidor Linux con Docker y Docker Compose
- Instancia de Gitea o Forgejo en funcionamiento
- Dominio con HTTPS configurado (requerido para OAuth)
- Mínimo 1 GB de RAM para el servidor
- Los agentes pueden estar en servidores separados
Configuración de la Aplicación OAuth en Gitea/Forgejo
Woodpecker usa OAuth2 para autenticar usuarios. Crea la aplicación OAuth en Gitea:
1. Ve a: Tu perfil > Ajustes > Aplicaciones
2. En "Gestionar aplicaciones OAuth2", haz clic en "Crear nueva aplicación OAuth2"
3. Nombre: Woodpecker CI
4. URL de redirección: https://ci.tudominio.com/authorize
5. Haz clic en "Crear aplicación"
6. Guarda el Client ID y Client Secret que se generan
Instalación del Servidor Woodpecker
# Crear directorio de trabajo
mkdir -p /opt/woodpecker
cd /opt/woodpecker
# Generar un secret compartido entre servidor y agentes
WOODPECKER_AGENT_SECRET=$(openssl rand -hex 32)
echo "Agent Secret: $WOODPECKER_AGENT_SECRET"
Crea el fichero docker-compose.yml:
# /opt/woodpecker/docker-compose.yml
version: "3.8"
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
container_name: woodpecker-server
restart: unless-stopped
ports:
- "8000:8000" # Puerto web
- "9000:9000" # Puerto gRPC para agentes
environment:
# Configuración del servidor
- WOODPECKER_HOST=https://ci.tudominio.com
- WOODPECKER_OPEN=false # Solo usuarios autorizados
- WOODPECKER_ADMIN=tu_usuario_gitea
# Secreto compartido con los agentes
- WOODPECKER_AGENT_SECRET=TU_AGENT_SECRET_AQUI
# Integración con Gitea
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=https://git.tudominio.com
- WOODPECKER_GITEA_CLIENT=TU_OAUTH_CLIENT_ID
- WOODPECKER_GITEA_SECRET=TU_OAUTH_CLIENT_SECRET
# Base de datos (SQLite para empezar, PostgreSQL para producción)
- WOODPECKER_DATABASE_DRIVER=sqlite3
- WOODPECKER_DATABASE_DATASOURCE=/var/lib/woodpecker/woodpecker.sqlite
volumes:
- woodpecker_server_data:/var/lib/woodpecker/
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
container_name: woodpecker-agent
restart: unless-stopped
depends_on:
- woodpecker-server
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=TU_AGENT_SECRET_AQUI
- WOODPECKER_MAX_PROCS=4 # Pipelines paralelos por agente
- WOODPECKER_BACKEND=docker
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- woodpecker_agent_data:/etc/woodpecker
volumes:
woodpecker_server_data:
woodpecker_agent_data:
# Arrancar Woodpecker
docker compose up -d
# Verificar los logs de inicio
docker compose logs -f woodpecker-server
Configura el proxy inverso con Nginx:
sudo tee /etc/nginx/sites-available/woodpecker << 'EOF'
server {
listen 443 ssl http2;
server_name ci.tudominio.com;
ssl_certificate /etc/letsencrypt/live/ci.tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ci.tudominio.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
# Necesario para streaming de logs en tiempo real
proxy_buffering off;
proxy_read_timeout 3600s;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/woodpecker \
/etc/nginx/sites-enabled/woodpecker
sudo certbot --nginx -d ci.tudominio.com
sudo systemctl reload nginx
Instalación de Agentes
Los agentes pueden desplegarse en servidores separados para escalar la capacidad de compilación:
# En el servidor del agente (puede ser diferente al del servidor)
mkdir -p /opt/woodpecker-agent
cd /opt/woodpecker-agent
tee docker-compose.yml << 'EOF'
version: "3.8"
services:
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
restart: unless-stopped
environment:
# Apuntar al servidor Woodpecker
- WOODPECKER_SERVER=ci.tudominio.com:9000
- WOODPECKER_AGENT_SECRET=EL_MISMO_AGENT_SECRET
- WOODPECKER_MAX_PROCS=2
- WOODPECKER_BACKEND=docker
# Etiquetar este agente para pipelines específicos
- WOODPECKER_LABELS=platform=linux,arch=amd64
volumes:
- /var/run/docker.sock:/var/run/docker.sock
EOF
docker compose up -d
Sintaxis de Pipelines
Crea el fichero .woodpecker.yml en la raíz de tu repositorio:
# Pipeline básico de CI
steps:
# Paso de pruebas
pruebas:
image: node:20-alpine
commands:
- npm ci
- npm test
- npm run lint
# Construcción de imagen Docker
construir:
image: plugins/docker
settings:
repo: registro.tudominio.com/mi-app
tags:
- latest
- ${CI_COMMIT_SHA}
username:
from_secret: docker_username
password:
from_secret: docker_password
when:
branch: main
# Despliegue en producción
desplegar:
image: appleboy/drone-ssh
settings:
host: produccion.tudominio.com
username: deploy
key:
from_secret: ssh_private_key
script:
- cd /opt/mi-app
- docker compose pull
- docker compose up -d --remove-orphans
when:
branch: main
event: push
Pipeline con múltiples etapas y dependencias:
# Pipeline con etapas secuenciales
steps:
instalar:
image: node:20
commands:
- npm ci
pruebas-unitarias:
image: node:20
commands:
- npm run test:unit
depends_on: [instalar]
pruebas-integracion:
image: node:20
commands:
- npm run test:integration
depends_on: [instalar]
construir:
image: node:20
commands:
- npm run build
depends_on:
- pruebas-unitarias
- pruebas-integracion
notificar-fallo:
image: curlimages/curl
commands:
- |
curl -X POST "$TELEGRAM_URL" \
-d "chat_id=$CHAT_ID&text=❌ Pipeline fallido en $CI_REPO"
when:
status: [failure]
depends_on: [construir]
Gestión de Secretos
Los secretos se configuran desde la interfaz web o mediante la CLI:
# Instalar la CLI de Woodpecker
curl -sL https://github.com/woodpecker-ci/woodpecker/releases/latest/download/woodpecker-cli-linux-amd64.tar.gz \
| tar -xz -C /usr/local/bin/
# Configurar la CLI
export WOODPECKER_SERVER=https://ci.tudominio.com
export WOODPECKER_TOKEN=TU_TOKEN_API
# Crear un secreto para un repositorio específico
woodpecker secret add \
--repository tu-org/mi-app \
--name docker_password \
--value "contraseña_docker_segura"
# Crear un secreto global (disponible en todos los repositorios)
woodpecker secret add \
--global \
--name ssh_private_key \
--value "$(cat ~/.ssh/id_rsa)"
# Listar secretos de un repositorio
woodpecker secret ls --repository tu-org/mi-app
En el pipeline, accede a los secretos:
steps:
desplegar:
image: alpine
environment:
# Los secretos se inyectan como variables de entorno
API_KEY:
from_secret: mi_api_key
commands:
- echo "Usando la clave API: $API_KEY"
Compilaciones Multi-plataforma
Configura compilaciones para múltiples arquitecturas (amd64, arm64):
# Pipeline multi-plataforma
platform: linux/amd64,linux/arm64
steps:
construir-imagen:
image: plugins/docker
settings:
platforms: linux/amd64,linux/arm64
repo: registro.tudominio.com/mi-app
tags: [latest, "${CI_COMMIT_SHA}"]
username:
from_secret: docker_username
password:
from_secret: docker_password
when:
branch: main
Para agentes específicos por arquitectura:
# Ejecutar en un agente ARM específico
labels:
platform: linux/arm64
steps:
pruebas-arm:
image: golang:1.22-alpine
commands:
- go test ./...
Solución de Problemas
El agente no se conecta al servidor:
# Verificar que el puerto gRPC (9000) está accesible
telnet ci.tudominio.com 9000
# Comprobar el secret en ambos lados
docker exec woodpecker-server env | grep AGENT_SECRET
docker exec woodpecker-agent env | grep AGENT_SECRET
Pipeline falla al hacer pull de la imagen:
# Verificar credenciales del registro Docker
docker exec woodpecker-agent \
docker login registro.tudominio.com
# Ver logs del agente durante la ejecución
docker compose logs -f woodpecker-agent
OAuth no redirige correctamente:
# Verificar que la URL de callback coincide exactamente
# En Gitea: Ajustes > Aplicaciones > OAuth2
# URL de redirección debe ser: https://ci.tudominio.com/authorize
# Revisar logs del servidor
docker compose logs woodpecker-server | grep -i oauth
Conclusión
Woodpecker CI ofrece una solución de integración continua nativa de contenedores, sencilla de operar y perfectamente integrada con Gitea y Forgejo. Su arquitectura de servidor y agentes permite escalar horizontalmente la capacidad de compilación según las necesidades del equipo, mientras que la sintaxis YAML simple facilita la definición de pipelines complejos. Es la combinación ideal para equipos que ya utilizan Gitea o Forgejo como plataforma de hosting Git.


