Woodpecker CI Docker Compose: CI/CD Self-Hosted 2026

Woodpecker CI Docker Compose ejecutando un pipeline self-hosted

Montar Woodpecker CI Docker Compose te da integración continua propia en dos contenedores y unos 100 MB de RAM. Sin minutos que se agotan, sin cola compartida y sin que tu código salga de tu servidor. Si ya tienes tu forja Git en casa, este es el complemento natural.

Es una alternativa ligera a Jenkins y a los runners de GitHub Actions: sintaxis YAML muy parecida a la que ya conoces, pero sin una JVM ni un ecosistema de plugins que mantener.

Qué es Woodpecker CI y por qué en Docker Compose

Woodpecker nació como un fork de Drone cuando este cambió de licencia, y hoy es un proyecto comunitario con licencia Apache 2.0. Su arquitectura tiene solo dos piezas, y entenderlas te ahorra el 90 % de los problemas de instalación.

ComponenteFunción
ServerInterfaz web, autenticación contra la forja, cola de trabajos y base de datos.
AgentEjecuta los pasos del pipeline como contenedores. Puede haber varios.

En Woodpecker CI Docker Compose ambos hablan por gRPC en el puerto 9000 usando un secreto compartido. El servidor no ejecuta nada: solo reparte. Esa separación es lo que permite tener el servidor en una máquina modesta y los agentes en otra con más músculo.

Frente a alternativas más pesadas, la ventaja de resolverlo con Woodpecker CI Docker Compose es el consumo: donde un servidor Jenkins te pide un par de gigas para estar cómodo, aquí te sobra con medio.

Frente a las alternativas

WoodpeckerJenkinsGitLab CI
RAM en reposo~100 MB1-2 GB4 GB o más
ConfiguraciónYAML en el repoGroovy o interfazYAML en el repo
ExtensionesPlugins como imágenesCatálogo enormeIntegrado
CurvaBajaAltaMedia

Lo interesante de la fila de extensiones: aquí un plugin no es un artefacto que instalas en el servidor y que puede romperte una actualización, sino simplemente una imagen de contenedor que se ejecuta en un paso. Eso elimina de un plumazo el problema clásico de mantenimiento de Jenkins, y es una de las razones de peso para montar Woodpecker CI Docker Compose en lugar de heredar una instalación pesada.


Requisitos previos de Woodpecker CI Docker Compose

  • Una forja Git accesible: Forgejo, Gitea, GitHub o GitLab. Aquí usaremos Forgejo.
  • Un dominio con HTTPS. No es opcional: OAuth necesita una URL de retorno estable.
  • Docker Engine 24+ y unos 512 MB de RAM libres.
  • El socket de Docker disponible para el agente.

Si aún no tienes forja propia, el punto de partida es el tutorial de Forgejo con Docker Compose; también funciona igual de bien con Gitea, que comparte el mismo origen.

Configurar Woodpecker CI Docker Compose paso a paso

Paso 1: registrar la aplicación OAuth

Esto va primero, porque de aquí salen los dos valores que necesitarás en el compose. En Forgejo entra en Configuración → Aplicaciones → Aplicaciones OAuth2 y crea una nueva. La URL de retorno tiene que ser exacta:

https://ci.midominio.es/authorize

Guarda el client ID y el client secret que te devuelve. Si prefieres que la integración sea de toda la instancia y no de tu usuario, créala desde Administración → Aplicaciones OAuth2.

Paso 2: generar el secreto de agente

Servidor y agente se autentican con una cadena compartida. Genera una de verdad, no pongas «cambiame».

mkdir -p ~/woodpecker && cd ~/woodpecker
openssl rand -hex 32

Copia el resultado al fichero de variables junto al resto de datos.

cat > .env <<'EOF'
WOODPECKER_HOST=https://ci.midominio.es
WOODPECKER_FORGEJO_URL=https://git.midominio.es
WOODPECKER_FORGEJO_CLIENT=pega-aqui-el-client-id
WOODPECKER_FORGEJO_SECRET=pega-aqui-el-client-secret
WOODPECKER_AGENT_SECRET=pega-aqui-el-openssl-rand
WOODPECKER_ADMIN=tuusuario
EOF

chmod 600 .env

Paso 3: escribir el docker-compose.yml

Este es el docker-compose.yml completo de Woodpecker CI Docker Compose, basado en el ejemplo oficial pero adaptado a Forgejo y con el registro público cerrado.

services:
  woodpecker-server:
    image: woodpeckerci/woodpecker-server:v3
    container_name: woodpecker-server
    restart: always
    ports:
      - "8000:8000"
    volumes:
      - ./server-data:/var/lib/woodpecker/
    environment:
      - WOODPECKER_OPEN=false
      - WOODPECKER_ADMIN=${WOODPECKER_ADMIN}
      - WOODPECKER_HOST=${WOODPECKER_HOST}
      - WOODPECKER_FORGEJO=true
      - WOODPECKER_FORGEJO_URL=${WOODPECKER_FORGEJO_URL}
      - WOODPECKER_FORGEJO_CLIENT=${WOODPECKER_FORGEJO_CLIENT}
      - WOODPECKER_FORGEJO_SECRET=${WOODPECKER_FORGEJO_SECRET}
      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}

  woodpecker-agent:
    image: woodpeckerci/woodpecker-agent:v3
    container_name: woodpecker-agent
    command: agent
    restart: always
    depends_on:
      - woodpecker-server
    volumes:
      - ./agent-config:/etc/woodpecker
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WOODPECKER_SERVER=woodpecker-server:9000
      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
      - WOODPECKER_MAX_WORKFLOWS=2

Dos ajustes importantes respecto al ejemplo de la documentación. WOODPECKER_OPEN=false impide que cualquiera con cuenta en tu forja entre a la interfaz; sin eso, un servidor público se llena de desconocidos. Y WOODPECKER_MAX_WORKFLOWS limita cuántos trabajos ejecuta un agente en paralelo: dos es prudente para empezar.

Paso 4: levantar y verificar

docker compose up -d
docker compose logs -f woodpecker-agent

En los registros del agente debes ver que se conecta y queda a la espera. Si aparece un error de autenticación, el secreto no coincide entre ambos servicios: es el fallo número uno de esta instalación.

Advertencia: el socket de Docker

El agente monta /var/run/docker.sock, lo que equivale a darle control del host. Cualquiera que pueda escribir un pipeline en un repositorio conectado puede ejecutar lo que quiera en esa máquina. Conecta solo repositorios de confianza, y si vas a aceptar aportaciones externas, pon el agente en una máquina aislada.

Paso 5: publicar con HTTPS

OAuth no funciona en claro, así que necesitas un proxy inverso delante. Con Traefik y certificados automáticos son cinco etiquetas.

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.woodpecker.rule=Host(`ci.midominio.es`)"
      - "traefik.http.routers.woodpecker.entrypoints=websecure"
      - "traefik.http.routers.woodpecker.tls.certresolver=letsencrypt"
      - "traefik.http.services.woodpecker.loadbalancer.server.port=8000"

Si Forgejo corre en el mismo host, añade el agente a su misma red de Docker: el agente clona usando la URL que le devuelve la API de la forja, y si no la alcanza, los pipelines fallan en el primer paso.


Tu primer pipeline en Woodpecker CI Docker Compose

Con Woodpecker CI Docker Compose ya en marcha, entra en la interfaz, inicia sesión con tu forja y activa un repositorio. Después crea el fichero .woodpecker.yml en su raíz.

when:
  - event: push
    branch: main

steps:
  - name: dependencias
    image: node:22-alpine
    commands:
      - npm ci

  - name: pruebas
    image: node:22-alpine
    commands:
      - npm test

  - name: construir imagen
    image: woodpeckerci/plugin-docker-buildx
    settings:
      repo: git.midominio.es/miusuario/mi-app
      registry: git.midominio.es
      tags: latest
      username:
        from_secret: registro_usuario
      password:
        from_secret: registro_token

Cada paso corre en su propio contenedor y comparte el directorio de trabajo con los demás. La sintaxis resultará familiar si vienes de GitHub Actions, con la diferencia de que aquí eliges la imagen de cada paso explícitamente.

Los valores from_secret se definen en la configuración del repositorio dentro de la interfaz, nunca en el fichero. Puedes marcarlos para que no estén disponibles en pipelines de pull requests externas, que es justo lo que evita que alguien te robe las credenciales con un PR malicioso. El catálogo de plugins oficiales cubre despliegues, notificaciones y publicación de artefactos.

Secretos y matrices en Woodpecker CI Docker Compose

Dos funciones de Woodpecker CI Docker Compose que vas a necesitar en cuanto el pipeline pase de «hola mundo». La primera son los secretos, que se definen por repositorio, por organización o globales desde la interfaz, y nunca se escriben en el YAML.

ÁmbitoCuándo usarlo
RepositorioCredenciales de despliegue de un solo proyecto.
OrganizaciónToken del registro de contenedores compartido.
GlobalNotificaciones o claves comunes a toda la instancia.

Al crear cada secreto eliges en qué eventos está disponible. Deja siempre desmarcado pull_request para los secretos con permisos de escritura: es la puerta clásica por la que se filtran credenciales desde una aportación externa.

La segunda función son las matrices, que multiplican un pipeline por cada combinación de valores. Muy útil para probar varias versiones de un lenguaje sin duplicar pasos.

matrix:
  NODE_VERSION:
    - 20
    - 22
    - 24

steps:
  - name: pruebas
    image: node:${NODE_VERSION}-alpine
    commands:
      - npm ci
      - npm test

Eso lanza tres ejecuciones en paralelo, repartidas entre los agentes disponibles. Ojo con el consumo: una matriz de nueve combinaciones en un servidor con un solo agente y dos workflows simultáneos tarda lo que tarda. La referencia de sintaxis de workflows recoge el resto de opciones, incluidas las condiciones por rama, por ruta modificada y por resultado de pasos anteriores.


Escalar y mantener Woodpecker CI Docker Compose

Cuando la cola de Woodpecker CI Docker Compose empiece a acumularse, no toques el servidor: añade agentes. Basta con duplicar el bloque del agente con otro nombre, o llevarlo a otra máquina apuntando al mismo servidor.

  • Base de datos. Por defecto usa SQLite en /var/lib/woodpecker. Para varios agentes y uso intenso, pásate a PostgreSQL con WOODPECKER_DATABASE_DRIVER.
  • Limpieza. Los contenedores de pipeline dejan capas huérfanas; programa un docker system prune semanal en los agentes.
  • Copias. Respalda el volumen del servidor: ahí viven usuarios, secretos e historial. Los agentes son desechables.
  • Actualizaciones. Sube servidor y agentes a la vez; versiones distintas pueden dejar de entenderse por gRPC.

Añadir un segundo agente

Crecer es literalmente copiar y pegar un bloque. El nuevo agente se registra solo contra el servidor en cuanto arranca con el secreto correcto, sin tocar nada en la interfaz.

  woodpecker-agent-2:
    image: woodpeckerci/woodpecker-agent:v3
    container_name: woodpecker-agent-2
    command: agent
    restart: always
    depends_on:
      - woodpecker-server
    volumes:
      - ./agent2-config:/etc/woodpecker
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WOODPECKER_SERVER=woodpecker-server:9000
      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
      - WOODPECKER_MAX_WORKFLOWS=2

Fíjate en que cada agente necesita su propio directorio de configuración: ahí guarda su identificador tras registrarse, y si dos comparten volumen se pisan el uno al otro. Para llevarlo a otra máquina el cambio es sustituir woodpecker-server:9000 por la dirección real del servidor y abrir ese puerto entre ambas, preferiblemente por red privada o VPN y nunca expuesto a Internet.

Problemas frecuentes de Woodpecker CI Docker Compose

SíntomaCausaSolución
El agente no conectaSecreto distintoIgualar WOODPECKER_AGENT_SECRET
Error OAuth al entrarURL de retorno malDebe acabar en /authorize
Falla al clonarEl agente no ve la forjaMisma red Docker
El webhook no llegaForja bloquea host localALLOWED_HOST_LIST=external,loopback
Pipelines en colaLímite de workflowsSubir el valor o añadir agentes

El cuarto es específico de Forgejo y Gitea: por seguridad no envían webhooks a direcciones internas salvo que se lo permitas expresamente en app.ini.

Hay un quinto problema que no cabe en la tabla porque su diagnóstico es más largo: pipelines que funcionan en tu portátil y fallan en el agente. Casi siempre es el directorio de trabajo. Cada paso arranca un contenedor nuevo y solo se comparte el volumen del repositorio clonado, así que todo lo que instales fuera de esa ruta desaparece al pasar al paso siguiente. Si un paso instala dependencias en /usr/local y el siguiente las necesita, no las encontrará.

La solución es usar la misma imagen en los pasos encadenados e instalar dentro del propio repositorio —node_modules, entornos virtuales de Python o similares—, o bien declarar un volumen de caché compartido. Comprobar esto primero te ahorra dar vueltas buscando fallos de permisos que no existen.

Conclusión sobre Woodpecker CI Docker Compose

Woodpecker CI Docker Compose no pretende competir con GitLab CI en funciones, y ahí está su gracia: hace lo que necesita el 90 % de los proyectos con una fracción de los recursos. Si tu equipo es pequeño y ya alojas tu propio Git, cierras el círculo completo —código, CI y registro de imágenes— en un único servidor modesto.

Empieza con Woodpecker CI Docker Compose conectando un solo repositorio con un pipeline de dos pasos y vete creciendo. Tienes el proyecto en su repositorio de GitHub, la guía de despliegue en la documentación oficial de Docker Compose, los detalles de la integración en la página de Forgejo y más ideas en los tutoriales de Docker Compose.

Preguntas frecuentes sobre Woodpecker CI Docker Compose

¿Sirve con GitHub o GitLab?

Sí. Cambia el bloque de variables por WOODPECKER_GITHUB o WOODPECKER_GITLAB con sus credenciales OAuth. Todo lo demás es idéntico, y puedes tener repositorios de varias forjas si levantas más de un servidor.

¿Cuánto consume realmente?

Servidor y agente en reposo rondan los 100 MB de RAM juntos. El consumo real lo marcan los contenedores de cada paso del pipeline, que es donde debes dimensionar la máquina.

¿Puedo migrar mis workflows de GitHub Actions?

No directamente, pero la traducción es mecánica: los jobs pasan a steps, cada uno con su image y sus commands. Lo que no existe es el catálogo de acciones de terceros; ahí usarás plugins o comandos a pelo.

¿Necesito un agente por proyecto?

No. Un agente atiende todos los repositorios y ejecuta tantos trabajos en paralelo como indique WOODPECKER_MAX_WORKFLOWS. Se añaden más agentes por capacidad, no por proyecto.

¿Es seguro exponerlo a Internet?

Con WOODPECKER_OPEN=false, HTTPS y administradores definidos, sí para un equipo. Ten presente siempre que el agente controla el host por el socket de Docker: la confianza que das a un repositorio conectado es total.

Avatar

Por Mid

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x
()
x