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.yml en 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 No (OSS)
Multi-pipeline No (OSS) No
Backend Kubernetes No 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.yml con 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-cli permite gestionar pipelines, secretos y tareas cron desde la terminal.

Artículos Relacionados