[{"data":1,"prerenderedAt":181},["ShallowReactive",2],{"seo-verification":3,"blog-reemplazar-github-actions-con-woodpecker-ci-en-vps-es":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-reemplazar-github-actions-con-woodpecker-ci-en-vps-es",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":29,"intro":32,"sections":33,"ctaTitle":108,"ctaBody":109,"ctaButton":110,"ctaUrl":111,"relatedPosts":112},338,"reemplazar-github-actions-con-woodpecker-ci-en-vps",{"fr":12,"en":13,"ar":14,"es":10},"remplacer-github-actions-woodpecker-ci-self-hosted-vps","replace-github-actions-with-woodpecker-ci-on-a-vps","استبدال-github-actions-بـwoodpecker-ci-على-vps","Reemplazar GitHub Actions con Woodpecker CI en VPS","GitHub anunció y luego suspendió la facturación de runners self-hosted. Migra a Woodpecker CI: sintaxis limpia, menos de 50 MB RAM, coste fijo en VPS.",8,1,false,"2026-09-07T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},2,"Automatización","automatisation","bg-brand-action\u002F10 text-brand-action",[28],{"id":23,"name":24,"slug":25,"color":26,"icon":25},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fremplacer-github-actions-woodpecker-ci-self-hosted-vps-poster.svg","En diciembre de 2025, GitHub anunció la facturación por minuto del uso de self-hosted runners en repositorios privados (discusión de la comunidad #182089, 72 votos). Ante una reacción masiva de la comunidad, la tarificación fue suspendida en menos de 48 horas — y a 1 de septiembre de 2026, los runners self-hosted siguen siendo gratuitos y la medida nunca llegó a aplicarse. La amenaza es real, sin embargo: nada impide que GitHub la reactive. Migrar a Woodpecker CI es protegerse del próximo anuncio — y ganar de paso la soberanía total sobre el CI\u002FCD. Woodpecker CI es una alternativa open source que funciona con menos de 50 MB de RAM, se conecta a Gitea o Forgejo mediante OAuth2 y no tiene contador de minutos.",[34,38,70,73,95,98,102,105],{"type":35,"title":36,"body":37},"h2","GitHub y la tarificación de runners: lo que ocurrió en 2025-2026","Hasta 2025, los repositorios privados tenían una cuota mensual de minutos incluidos. El 16 de diciembre de 2025, GitHub anunció precios por minuto para el uso de runners — incluidos los **self-hosted runners** que corren en tus propias máquinas. La discusión de GitHub #182089 (diciembre de 2025, 72 votos) resume la preocupación: los equipos habrían pagado a GitHub por orquestar un trabajo corriendo en su propia infraestructura, a 0,002 $ por minuto.\n\nAnte una reacción masiva de la comunidad, GitHub suspendió la tarificación en menos de 48 horas. A 1 de septiembre de 2026, los runners self-hosted en repos privados siguen siendo gratuitos — la medida nunca llegó a aplicarse. Pero el anuncio dejó al descubierto una dependencia estructural: GitHub puede cambiar sus condiciones en cualquier momento. Trasladar toda la cadena CI\u002FCD a una forja self-hosted es la manera de eliminar esa incertidumbre. Woodpecker CI está diseñado exactamente para esto: un motor de pipeline ligero, open source (Apache 2.0), que se instala junto a Gitea o Forgejo y no tiene contador de minutos.",{"type":39,"title":40,"headers":41,"rows":45},"comparison","GitHub Actions runners vs Woodpecker CI self-hosted",[42,43,44],"Criterio","GitHub Actions (runners cloud)","Woodpecker CI en VPS",[46,50,54,58,62,66],[47,48,49],"Coste","0,008 $ \u002F min (Linux) + 0,002 $ \u002F min orquestación en repos privados","Incluido en el coste fijo del VPS (desde `{{vps.start.price}}`)",[51,52,53],"RAM del motor CI","Runners GitHub-hosted: recursos compartidos, no controlados","Servidor + agente Woodpecker: menos de 50 MB RAM combinados",[55,56,57],"Soberanía","El código y los secretos pasan por la infraestructura de GitHub\u002FMicrosoft","Todo permanece en tu VPS — sin tránsito externo",[59,60,61],"Sintaxis de workflow","`.github\u002Fworkflows\u002F*.yml` — estándar muy extendido","`.woodpecker.yml` — sintaxis propia, más corta, no compatible con GitHub Actions",[63,64,65],"Forja requerida","Ninguna (GitHub aloja el repositorio)","Gitea o Forgejo self-hosted",[67,68,69],"Licencia","Propietaria","Apache 2.0",{"type":35,"title":71,"body":72},"Requisitos previos antes de la instalación","Para desplegar Woodpecker CI cómodamente, verifica los siguientes requisitos.\n\n**VPS**: 1 vCPU y 1 GB de RAM son suficientes para el servidor Woodpecker, un agente y una forja Gitea o Forgejo ligera. Cuenta con 2 GB si ejecutas varios builds en paralelo o tus jobs construyen imágenes Docker.\n\n**Software**: Docker y Docker Compose deben estar instalados. Si partes de un VPS limpio, la guía \u003Ca href=\"\u002Fblog\u002Fdemarrer-avec-docker-vps\">Empezar con Docker en VPS\u003C\u002Fa> cubre este paso.\n\n**Forja git**: Woodpecker CI utiliza OAuth2 para la autenticación. Necesitas una instancia de Gitea o Forgejo ya en marcha y accesible vía HTTPS. Las guías \u003Ca href=\"\u002Fblog\u002Fheberger-gitea\">Alojar Gitea\u003C\u002Fa> y \u003Ca href=\"\u002Fblog\u002Fheberger-forgejo\">Alojar Forgejo\u003C\u002Fa> detallan esta instalación.\n\n**Dominio**: prepara un subdominio dedicado para Woodpecker — por ejemplo `ci.tu-dominio.com` — apuntando a la IP de tu VPS con el puerto 443 abierto. Este subdominio sirve como `WOODPECKER_HOST` y como URL de redirección OAuth2.",{"type":74,"title":75,"steps":76},"steps","Instalar Woodpecker CI con Docker Compose",[77,80,83,86,89,92],{"title":78,"body":79},"Crear una aplicación OAuth2 en Gitea","En Gitea, ve a **Configuración → Aplicaciones → Gestionar aplicaciones OAuth2**. Da un nombre a la aplicación (por ejemplo `woodpecker`) e introduce la URL de redirección: `https:\u002F\u002Fci.tu-dominio.com\u002Fauthorize`. Anota el **Client ID** y el **Client Secret** generados — los necesitarás en el paso siguiente.\n\nSi usas Forgejo, el procedimiento es idéntico: **Configuración → Aplicaciones → OAuth2**.",{"title":81,"body":82},"Crear el archivo docker-compose.yml","Crea el directorio `\u002Fopt\u002Fwoodpecker` y coloca en él un archivo `docker-compose.yml` con los dos servicios — servidor y agente:\n\n```yaml\nservices:\n  woodpecker-server:\n    image: woodpeckerci\u002Fwoodpecker-server:v3\n    restart: always\n    ports:\n      - \"8000:8000\"\n    volumes:\n      - woodpecker-server-data:\u002Fvar\u002Flib\u002Fwoodpecker\u002F\n    environment:\n      - WOODPECKER_OPEN=false\n      - WOODPECKER_HOST=https:\u002F\u002Fci.tu-dominio.com\n      - WOODPECKER_GITEA=true\n      - WOODPECKER_GITEA_URL=https:\u002F\u002Fgit.tu-dominio.com\n      - WOODPECKER_GITEA_CLIENT=${WOODPECKER_GITEA_CLIENT}\n      - WOODPECKER_GITEA_SECRET=${WOODPECKER_GITEA_SECRET}\n      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}\n\n  woodpecker-agent:\n    image: woodpeckerci\u002Fwoodpecker-agent:v3\n    restart: always\n    command: agent\n    depends_on:\n      - woodpecker-server\n    volumes:\n      - woodpecker-agent-config:\u002Fetc\u002Fwoodpecker\n      - \u002Fvar\u002Frun\u002Fdocker.sock:\u002Fvar\u002Frun\u002Fdocker.sock\n    environment:\n      - WOODPECKER_SERVER=woodpecker-server:9000\n      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}\n\nvolumes:\n  woodpecker-server-data:\n  woodpecker-agent-config:\n```\n\nEl servidor escucha internamente en el puerto **8000** (interfaz web) y **9000** (gRPC, comunicación con el agente). No expongas estos puertos directamente: un proxy inverso gestiona el TLS.",{"title":84,"body":85},"Crear el archivo .env","En `\u002Fopt\u002Fwoodpecker`, crea un archivo `.env` con las tres variables sensibles:\n\n```\nWOODPECKER_GITEA_CLIENT=\u003Coauth2-client-id>\nWOODPECKER_GITEA_SECRET=\u003Coauth2-client-secret>\nWOODPECKER_AGENT_SECRET=\u003Ccadena-aleatoria-larga>\n```\n\nGenera `WOODPECKER_AGENT_SECRET` con `openssl rand -hex 32`. Esta cadena autentica al agente con el servidor — no la compartas.",{"title":87,"body":88},"Configurar el proxy inverso nginx","Coloca Woodpecker detrás de nginx con un certificado Let's Encrypt. Ejemplo de bloque `server` para `ci.tu-dominio.com`:\n\n```nginx\nserver {\n    listen 443 ssl;\n    server_name ci.tu-dominio.com;\n    ssl_certificate \u002Fetc\u002Fletsencrypt\u002Flive\u002Fci.tu-dominio.com\u002Ffullchain.pem;\n    ssl_certificate_key \u002Fetc\u002Fletsencrypt\u002Flive\u002Fci.tu-dominio.com\u002Fprivkey.pem;\n    location \u002F {\n        proxy_pass http:\u002F\u002F127.0.0.1:8000;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-Proto https;\n    }\n}\n```\n\nObtén el certificado con `certbot certonly --nginx -d ci.tu-dominio.com` y recarga nginx con `systemctl reload nginx`.",{"title":90,"body":91},"Arrancar la stack","Desde `\u002Fopt\u002Fwoodpecker`, ejecuta:\n\n```bash\ndocker compose up -d\n```\n\nSigue los logs del servidor hasta ver la línea de listo:\n\n```bash\ndocker compose logs -f woodpecker-server\n```\n\nAbre `https:\u002F\u002Fci.tu-dominio.com` en tu navegador. La página de inicio de sesión muestra un botón **Iniciar sesión con Gitea**. Haz clic: Gitea solicita autorización OAuth2 y te redirige al dashboard de Woodpecker.",{"title":93,"body":94},"Activar un repositorio y lanzar el primer build","En el dashboard de Woodpecker, haz clic en **+ Añadir repositorio**. Aparece tu lista de repositorios Gitea. Selecciona un proyecto y actívalo. Woodpecker registra automáticamente un webhook en Gitea para lanzar builds en cada push.\n\nRealiza un primer commit en ese repositorio: si el archivo `.woodpecker.yml` está en la raíz, el pipeline se dispara inmediatamente en la interfaz.",{"type":35,"title":96,"body":97},"Migrar un workflow de GitHub Actions a .woodpecker.yml","Woodpecker CI tiene su propia sintaxis YAML — no es compatible con GitHub Actions. La buena noticia: es más corta. Aquí tienes la migración de un workflow clásico de Node.js.\n\n**Antes — `.github\u002Fworkflows\u002Fci.yml`:**\n\n```yaml\nname: CI\non: [push, pull_request]\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: '20'\n      - run: npm ci\n      - run: npm test\n```\n\n**Después — `.woodpecker.yml`:**\n\n```yaml\nsteps:\n  - name: test\n    image: node:20\n    commands:\n      - npm ci\n      - npm test\n```\n\nDiferencias clave: Woodpecker usa directamente una imagen Docker como entorno de ejecución (no necesita `setup-node`), y cada paso es un servicio de contenedor. La acción `checkout` es implícita — Woodpecker clona automáticamente el repositorio en el espacio de trabajo compartido entre los pasos.",{"type":99,"title":100,"body":101},"tip","Secretos de pipeline y la variable WOODPECKER_SECRET","Nunca pongas tokens, claves SSH ni contraseñas en tu `.woodpecker.yml` versionado. Woodpecker gestiona los secretos a nivel de repositorio u organización: en el dashboard, abre el repositorio → **Configuración → Secretos → Añadir secreto**. Cada secreto se inyecta como variable de entorno en tiempo de build.\n\nPara usar un secreto en el pipeline:\n\n```yaml\nsteps:\n  - name: deploy\n    image: alpine\n    environment:\n      SSH_DEPLOY_KEY:\n        from_secret: ssh_deploy_key\n    commands:\n      - echo \"$SSH_DEPLOY_KEY\" > \u002Ftmp\u002Fid_rsa\n      - chmod 600 \u002Ftmp\u002Fid_rsa\n      - ssh -i \u002Ftmp\u002Fid_rsa deploy@tu-dominio.com .\u002Fdeploy.sh\n```\n\nLa sintaxis `from_secret` extrae el valor del almacén de Woodpecker sin escribirlo en los logs ni en el archivo YAML.",{"type":35,"title":103,"body":104},"Resolución de problemas habituales","**El agente no aparece en el dashboard.** Verifica que `WOODPECKER_AGENT_SECRET` sea idéntico en ambos servicios del `docker-compose.yml`. Si modificaste el `.env` después del primer arranque, reinicia con `docker compose down && docker compose up -d`.\n\n**El inicio de sesión OAuth2 falla.** La URL de redirección registrada en Gitea debe coincidir exactamente con `https:\u002F\u002Fci.tu-dominio.com\u002Fauthorize`. Una barra final, un error tipográfico o HTTP en lugar de HTTPS son suficientes para bloquear el flujo OAuth2. Comprueba también que `WOODPECKER_GITEA_URL` apunte a la URL **pública** de tu Gitea.\n\n**El webhook no se dispara.** Abre el repositorio en Gitea → **Configuración → Webhooks** y verifica que el webhook de Woodpecker esté presente y que las entregas recientes no tengan errores 4xx.\n\n**Los builds fallan por falta de memoria.** El servidor y el agente de Woodpecker consumen menos de 50 MB en reposo — pero cada paso de build lanza un contenedor Docker adicional. En un VPS de 1 GB, limita los builds concurrentes añadiendo `WOODPECKER_MAX_PROCS=2` al entorno del servicio `woodpecker-agent`.",{"type":35,"title":106,"body":107},"Para ir más lejos","Una vez que el pipeline base funciona, varias optimizaciones valen la pena.\n\n**Multi-runner.** Añade un segundo servicio `woodpecker-agent` a tu `docker-compose.yml` (misma imagen, mismo `WOODPECKER_AGENT_SECRET`) para paralelizar los builds.\n\n**Caché Docker entre builds.** Monta un volumen Docker en el agente y activa la caché de capas Docker para evitar volver a descargar las imágenes en cada build.\n\n**Notificaciones.** Woodpecker puede notificar un canal de mensajería en cada build — Matrix, Slack, Telegram y Mattermost.\n\n**Pipeline condicional.** La sintaxis de Woodpecker permite restringir un paso a una rama o evento concreto:\n\n```yaml\nsteps:\n  - name: deploy\n    image: alpine\n    when:\n      branch: main\n      event: push\n    commands:\n      - .\u002Fdeploy.sh\n```\n\nPara profundizar en la configuración de pipelines, la guía \u003Ca href=\"\u002Fblog\u002Fwoodpecker-ci-pipeline-vps-forgejo\">Woodpecker CI y Forgejo: pipeline CI\u002FCD en VPS\u003C\u002Fa> detalla los pasos avanzados.","Un VPS ServOrbit para tu pipeline CI\u002FCD","El plan `{{vps.start.name}}` a `{{vps.start.price}}` — 1 vCPU, 1 GB RAM, IP fija — es suficiente para ejecutar Woodpecker CI, un agente y una forja Gitea en paralelo, sin contador de minutos.","Ver planes VPS Cloud","\u002Fvps-cloud",[113,128,146,166],{"id":114,"slug":115,"slugs":116,"title":120,"excerpt":121,"readTime":122,"views":18,"isPinned":19,"publishedAt":123,"updatedAt":21,"category":124,"categories":125,"featuredImage":29,"bgImage":30,"posterImage":127,"relatedSolution":29},212,"woodpecker-ci-forgejo-pipeline-cicd-vps",{"fr":117,"en":118,"ar":119,"es":115},"woodpecker-ci-pipeline-vps-forgejo","woodpecker-ci-and-forgejo-cicd-pipeline-on-a-vps","woodpecker-ci-وforgejo-خط-أنابيب-cicd-على-خادم-vps","Woodpecker CI y Forgejo: pipeline CI\u002FCD en un VPS","Despliega Woodpecker CI v3 con Forgejo en tu VPS: configuración Docker Compose, pipelines YAML, secretos, runners multi-arquitectura y depuración OAuth.",11,"2026-08-02T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[126],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Fwoodpecker-ci-pipeline-vps-forgejo-poster.svg",{"id":129,"slug":130,"slugs":131,"title":135,"excerpt":136,"readTime":122,"views":137,"isPinned":19,"publishedAt":138,"updatedAt":21,"category":139,"categories":140,"featuredImage":29,"bgImage":30,"posterImage":142,"relatedSolution":143},273,"migrar-cicd-a-gitea-o-forgejo-sin-github-actions",{"fr":132,"en":133,"ar":134,"es":130},"github-actions-payant-migrer-ci-cd-gitea-forgejo-vps","migrate-cicd-to-gitea-or-forgejo-leave-github-actions","gitea-وforgejo-بديل-github-actions-المدفوع-على-vps","Migrar su CI\u002FCD a Gitea o Forgejo: fuera de GitHub Actions","Desde marzo de 2026, GitHub cobra los minutos de CI en repositorios privados. Migre a Gitea Actions o Forgejo en un VPS: mismos archivos YAML, costo fijo.",0,"2026-08-16T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[141],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Fgithub-actions-payant-migrer-ci-cd-gitea-forgejo-vps-poster.svg",{"categorySlug":144,"appSlug":145},"desarrollo","gitea",{"id":147,"slug":148,"slugs":149,"title":153,"excerpt":154,"readTime":17,"views":137,"isPinned":19,"publishedAt":155,"updatedAt":21,"category":156,"categories":162,"featuredImage":29,"bgImage":30,"posterImage":164,"relatedSolution":165},74,"alojar-gitea-en-un-vps",{"fr":150,"en":151,"ar":152,"es":148},"heberger-gitea","host-gitea-on-your-own-vps","استضافة-gitea-على-خادم-vps-الخاص-بك","Alojar Gitea en su propio VPS en 2026","Despliegue Gitea en un VPS con Docker y SSL. Guía completa: instalación, migración a Forgejo v16 y comparativa de gobernanza.","2026-04-07T00:00:00+00:00",{"id":157,"name":158,"slug":159,"color":160,"icon":161},7,"Autoalojamiento","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[163],{"id":157,"name":158,"slug":159,"color":160,"icon":161},"\u002Fblog\u002Fcovers\u002Fheberger-gitea-poster.svg",{"categorySlug":144,"appSlug":145},{"id":167,"slug":168,"slugs":169,"title":173,"excerpt":174,"readTime":175,"views":23,"isPinned":19,"publishedAt":176,"updatedAt":21,"category":177,"categories":178,"featuredImage":29,"bgImage":30,"posterImage":180,"relatedSolution":29},75,"alojar-forgejo-en-un-vps",{"fr":170,"en":171,"ar":172,"es":168},"heberger-forgejo","host-forgejo-on-your-own-vps","استضافة-forgejo-على-خادم-vps-الخاص-بك","Alojar Forgejo en su VPS: guía completa 2025","Instale Forgejo en su VPS con Docker, SSL, runners Actions y seguridad reforzada. Guía paso a paso de 1900 palabras para una forja Git soberana.",9,"2026-04-06T00:00:00+00:00",{"id":157,"name":158,"slug":159,"color":160,"icon":161},[179],{"id":157,"name":158,"slug":159,"color":160,"icon":161},"\u002Fblog\u002Fcovers\u002Fheberger-forgejo-poster.svg",1789665033407]