Por qué abandonar los servicios CI cloud en favor de un pipeline en tu VPS
Los servicios CI cloud facturan por minuto de compilación e imponen colas compartidas cuyo tiempo de espera aumenta con el volumen. Cuando los repositorios crecen o los tests se multiplican, la factura supera rápidamente el coste de un VPS dedicado. Alojar Forgejo y Woodpecker CI en el mismo servidor elimina esta latencia de red: el runner lee el código localmente, sin pasar por infraestructura de terceros. También controlas el ciclo de actualizaciones — ningún cambio de precios o política de retención de logs se aplica sin tu consentimiento. Para equipos con restricciones regulatorias o de confidencialidad, esta es una ventaja decisiva: los secretos de integración (claves SSH de despliegue, tokens de acceso a registros) nunca cruzan el perímetro de tu red. Por último, la licencia Apache 2.0 garantiza que el código fuente permanezca auditable y que el proyecto no pueda quedar encerrado tras una oferta comercial exclusiva.
Lo que aporta Woodpecker CI en un VPS
- Aislamiento Docker por paso — cada step se ejecuta en su propio contenedor sin estado compartido entre jobs; un step que falla no corrompe los siguientes.
- Huella de memoria reducida — servidor + agente arrancan en menos de 50 MB de RAM combinados, dejando la mayor parte de los recursos para las compilaciones.
- Sintaxis YAML minimalista — un archivo
.woodpecker.yamlen la raíz del repositorio es suficiente para describir todo el pipeline; la sintaxis es más legible que GitHub Actions. - Integración nativa con Forgejo — el OAuth2 de Forgejo es el único mecanismo de autenticación requerido; los webhooks se registran automáticamente.
- Multi-arquitectura sin plugins adicionales — la clave
platform: linux/arm64basta para enrutar un job a un agente ARM64; no se necesita abstracción adicional. - Secretos centralizados por repositorio o globales — las variables sensibles se inyectan en tiempo de compilación y nunca aparecen en el archivo YAML versionado.
- Licencia Apache 2.0 — código fuente auditable, comunidad fork activa, sin dependencia de un proveedor propietario.
Requisitos medidos: VPS, Forgejo y red
Woodpecker CI puede instalarse en el mismo VPS que Forgejo o en un servidor dedicado. Para ambos servicios combinados, prevé al menos 1 GB de RAM y 2 GB para un uso cómodo con varios repositorios activos en paralelo. En cuanto al software: Docker Engine 24 o superior, Docker Compose v2 (el comando docker compose, no docker-compose), un subdominio dedicado a Woodpecker — por ejemplo ci.your-domain.com — apuntando a la IP del VPS, el puerto 443 abierto para HTTPS y acceso SSH. Forgejo debe ser accesible desde el contenedor de Woodpecker: ya sea a través de la red Docker interna si ambos servicios comparten el mismo host, o mediante su URL pública HTTPS si Woodpecker está en un VPS separado. Woodpecker CI v3 es compatible con Forgejo v1.20 y superior.
Woodpecker CI vs Forgejo Actions: cuándo usar cuál
Forgejo Actions — disponible desde Forgejo v1.19 en modo experimental, estabilizado progresivamente — replica la sintaxis de GitHub Actions: si tus equipos ya tienen flujos de trabajo .github/workflows/ en producción, la migración es casi transparente. Forgejo Actions es la elección natural para un parque de repositorios que coexiste con GitHub o reutiliza acciones públicas del marketplace. Woodpecker CI responde a necesidades diferentes: su sintaxis YAML es más directa, menos cargada de conceptos heredados de GitHub, y su arquitectura servidor-agente permite desacoplar la forja git del motor CI — útil cuando varios sistemas git necesitan compartir el mismo parque de runners. Woodpecker también es más adecuado para escenarios de compilación multi-arquitectura, donde se quiere enrutar explícitamente un job a un agente ARM o x86. En resumen: elige Forgejo Actions si la compatibilidad con GitHub Actions es prioritaria, y Woodpecker CI si prefieres una sintaxis depurada, un despliegue desacoplado o un parque de runners heterogéneo.
Desplegar Woodpecker CI en tu VPS
Crear una OAuth App en Forgejo
En Forgejo, ve a Ajustes → Aplicaciones → Gestionar aplicaciones OAuth2. Asigna un nombre a la aplicación (por ejemplo
woodpecker) e introduce la URL de redirección:https://ci.your-domain.com/authorize. Anota el Client ID y el Client Secret generados; se usarán en las variables de entorno del servidor Woodpecker.Generar un secreto compartido servidor-agente
Genera una cadena aleatoria robusta:
openssl rand -hex 32. Este valor se asignará comoWOODPECKER_AGENT_SECRETtanto en el servicio servidor como en el agente; autentifica la comunicación gRPC entre ambos. Guárdalo en un gestor de secretos o en un archivo.envno versionado.Crear el directorio y el docker-compose.yml
Crea el directorio
/opt/woodpecker/y coloca en él un archivodocker-compose.yml. El serviciowoodpecker-serverutiliza la imagenwoodpeckerci/woodpecker-server:v3y expone los puertos 8000 (UI) y 9000 (gRPC). Configura las variablesWOODPECKER_FORGEJO=true,WOODPECKER_FORGEJO_URL,WOODPECKER_FORGEJO_CLIENT,WOODPECKER_FORGEJO_SECRET,WOODPECKER_AGENT_SECRETyWOODPECKER_HOST=https://ci.your-domain.com. El serviciowoodpecker-agentusawoodpeckerci/woodpecker-agent:v3, monta/var/run/docker.socky recibeWOODPECKER_SERVER=woodpecker-server:9000más el mismoWOODPECKER_AGENT_SECRET.Configurar el reverse proxy HTTPS
Configura Traefik o Caddy para terminar TLS en
ci.your-domain.comy hacer proxy haciawoodpecker-server:8000. Con Caddy, un bloque mínimo es suficiente:ci.your-domain.com { reverse_proxy woodpecker-server:8000 }. Nunca expongas el puerto 8000 directamente en la IP pública; el puerto 9000 (gRPC) debe permanecer accesible solo en la red Docker interna.Arrancar el stack
En
/opt/woodpecker, ejecutadocker compose up -d. Comprueba los logs condocker compose logs -f woodpecker-serverhasta verserver started. El agente aparece en los logs del servidor con un mensajeagent connected; si no aparece en treinta segundos, verifica queWOODPECKER_AGENT_SECRETsea idéntico en ambos servicios.Iniciar sesión y activar el primer repositorio
Abre
https://ci.your-domain.come inicia sesión con tu cuenta de Forgejo mediante OAuth2. En el dashboard, haz clic en «Añadir repositorio» y selecciona el proyecto a activar. Woodpecker registra automáticamente un webhook en Forgejo para lanzar compilaciones en cada push o pull request.Añadir el archivo .woodpecker.yaml al repositorio
En la raíz del repositorio, crea
.woodpecker.yaml. Ejemplo mínimo con tres pasos:lint(imagennode:20, comandonpm run lint),test(imagennode:20, comandonpm test) ydeploycondicional a la ramamainque lanza un script SSH remoto. Sube el archivo: se lanza inmediatamente un pipeline en Woodpecker y el resultado aparece en la interfaz y en el estado del commit en Forgejo.Verificar la persistencia de datos
Por defecto, Woodpecker almacena su base de datos SQLite dentro del contenedor. Para una instalación duradera, monta un volumen con nombre en
/var/lib/woodpeckeren el servicio servidor y realiza copias de seguridad regulares de ese volumen. Un reinicio o actualización de la imagen sin volumen con nombre borra el historial de compilaciones y la configuración de los repositorios activados.
Escribir tu primer pipeline en .woodpecker.yaml
Un archivo .woodpecker.yaml describe una secuencia de pasos ejecutados de forma secuencial en contenedores Docker separados. Cada paso tiene un nombre, una imagen y una lista de comandos. Los pasos pueden compartir el workspace (directorio clonado) a través de un volumen montado automáticamente por Woodpecker. Para un proyecto Node.js, un pipeline básico incluye un paso lint (node:20, npm ci && npm run lint), un paso test (node:20, npm test) y un paso build (node:20, npm run build). Para un proyecto Docker, añade un paso que use el plugin oficial woodpeckerci/plugin-docker-buildx para construir y publicar la imagen en un registro. El disparo condicional se expresa con el bloque when: when: { branch: main, event: push } limita el paso de despliegue a la rama principal en los push directos, excluyendo los pull requests.
Secretos y variables de entorno en los pipelines
Woodpecker distingue dos niveles de secretos: secretos de repositorio (visibles solo en los pipelines del repositorio correspondiente) y secretos globales (accesibles a todos los repositorios, a crear con cuidado). Un secreto se declara en el dashboard — en la sección Secrets del repositorio — y luego se referencia en el pipeline con la sintaxis from_secret. Por ejemplo, una clave SSH de despliegue llamada deploy_key se inyecta en un paso mediante environment: { SSH_KEY: { from_secret: deploy_key } }. Los secretos nunca se pasan a pull requests de forks externos por defecto, evitando la exfiltración por un colaborador malicioso. Para variables no sensibles que deban compartirse entre múltiples repositorios, usa la variable WOODPECKER_ENVIRONMENT a nivel del servidor: los pares CLAVE=valor definidos ahí están disponibles en todos los pipelines sin declaración en el YAML.
Coloca el servidor Woodpecker detrás de Traefik o Caddy con HTTPS y nunca lo expongas directamente en el puerto 8000. Activa la autenticación por lista blanca (WOODPECKER_ADMIN) para restringir el acceso al dashboard a las cuentas Forgejo autorizadas. Almacena todos los secretos de pipeline (tokens SSH, claves de API, contraseñas de registro Docker) en los secretos de repositorio del dashboard de Woodpecker — se inyectan como variables de entorno durante la compilación sin aparecer en el .woodpecker.yaml versionado. Por último, monta un volumen Docker con nombre para persistir la base de datos SQLite de Woodpecker: un reinicio sin volumen borra el historial de compilaciones.
Runners multi-arquitectura: x86_64 y ARM64
Woodpecker CI v3 soporta de forma nativa agentes multi-arquitectura: cada agente anuncia su plataforma al servidor (linux/amd64, linux/arm64, linux/arm/v7) y el servidor enruta los jobs al agente con la plataforma correspondiente. Para declarar un job ARM64, añade platform: linux/arm64 a nivel del pipeline en .woodpecker.yaml. Si dispones de un VPS ARM (Ampere, Raspberry Pi 4 o servidor Hetzner ARM) y un VPS x86_64, despliega un agente en cada uno con el mismo WOODPECKER_AGENT_SECRET y deja que el servidor distribuya las compilaciones. Este mecanismo es útil para compilación cruzada de binarios, pruebas de compatibilidad de imágenes Docker en múltiples arquitecturas o validación de paquetes del sistema. El plugin woodpeckerci/plugin-docker-buildx va más allá y usa QEMU para producir imágenes multi-arch desde un solo agente, pero las compilaciones nativas en la arquitectura objetivo siempre son más rápidas.
Depuración: cinco errores frecuentes
Cinco problemas aparecen repetidamente durante la instalación o el uso de Woodpecker CI. Primero: el agente no se conecta al servidor (agent could not auth). Causa más frecuente: WOODPECKER_AGENT_SECRET no es idéntico en ambos servicios. Verifica con docker compose exec woodpecker-server env | grep AGENT_SECRET. Segundo: el login OAuth2 falla con Error while authenticating against OAuth provider. Causa probable: la URL de redirección en la aplicación OAuth2 de Forgejo no coincide exactamente con WOODPECKER_HOST. Comprueba la barra final y la coherencia del esquema HTTPS. Tercero: los pipelines quedan bloqueados en pending. El agente puede estar conectado pero su etiqueta de plataforma no coincide con ningún pipeline; elimina la cláusula platform si no es necesaria. Cuarto: los secretos no se inyectan en los pasos. Los secretos solo se pasan a pipelines activados en ramas internas, nunca en PRs de forks externos por defecto. Verifica que el evento que lo activa sea push o tag. Quinto: tras actualizar a v3.18, faltan logs de compilaciones antiguas. Esta versión incluye una migración del almacenamiento de logs; si la migración se interrumpe, reinicia el contenedor servidor con permisos de escritura en el volumen de datos para que se reanude.
Integración con el marketplace de ServOrbit: despliegue automático en VPS
ServOrbit ofrece Woodpecker CI en su marketplace: la aplicación se instala en un VPS Cloud con Docker preconfigurado e IP fija, en pocos clics desde el portal de cliente. Una vez aprovisionado el VPS, basta con apuntar WOODPECKER_FORGEJO_URL a tu forja Forgejo existente e introducir las claves OAuth2 para que los pipelines comiencen a ejecutarse. Esta integración es especialmente útil para agencias o equipos técnicos que quieren aislar el motor CI del servidor de forja: Forgejo en un VPS, Woodpecker en un segundo, comunicándose vía HTTPS. Los recursos del VPS son ajustables en cualquier momento desde el portal de cliente — añadir RAM o vCPU sin reinstalar — lo que permite dimensionar el parque de runners según la carga real de compilaciones.
De la forja git al despliegue continuo: una stack soberana completa
Forgejo gestiona el código, los issues y las revisiones de pull requests; Woodpecker CI orquesta los pipelines de test y despliegue. Los dos se comunican mediante OAuth2 y webhooks en tu propia red, sin dependencia de GitHub, GitLab o ningún servicio de integración cloud. Esta stack auto-alojada responde a las restricciones de soberanía de las agencias y equipos técnicos que no quieren que su propiedad intelectual o sus secretos de integración transiten por plataformas externas. Con Woodpecker CI v3 y Forgejo v1.20 o superior, dispones de un entorno de desarrollo completo — forja git, CI/CD, registro Docker si es necesario — completamente bajo tu control, en uno o dos VPS, con un coste mensual predecible y sin cuota de minutos de compilación.