Automatisation8 min de lecture

Remplacer GitHub Actions par Woodpecker CI sur VPS

En décembre 2025, GitHub a annoncé la facturation à la minute des self-hosted runners sur les dépôts privés (discussion communautaire #182089, 72 upvotes). Face à une réaction communautaire massive, cette tarification a été suspendue dans les 48 heures — et au 1er septembre 2026, les runners self-hosted restent gratuits. La menace est pourtant réelle : rien n'empêche GitHub de la réactiver. Migrer vers Woodpecker CI, c'est se prémunir contre la prochaine annonce — et gagner au passage la souveraineté sur son CI/CD. Woodpecker CI est une alternative open source qui tourne en moins de 50 Mo de RAM, fonctionne avec Gitea ou Forgejo via OAuth2, et reste gratuit tant que votre VPS tourne.

GitHub et la tarification des runners : ce qui s'est passé en 2025-2026

Jusqu'en 2025, les dépôts privés bénéficiaient d'un quota mensuel de minutes incluses. Le 16 décembre 2025, GitHub a annoncé une tarification à la minute pour l'utilisation des runners — y compris les runners auto-hébergés sur vos propres machines. La discussion GitHub #182089 (ouverte ce même mois, 72 upvotes) résume l'inquiétude : les équipes auraient payé GitHub pour l'orchestration d'un job tournant sur leur propre infrastructure, à 0,002 $ la minute.

Face à une réaction communautaire massive, GitHub a suspendu cette tarification dans les 48 heures. Au 1er septembre 2026, les runners self-hosted sur dépôts privés restent gratuits — la mesure n'a jamais été appliquée. Mais l'annonce a mis en évidence une dépendance structurelle : GitHub peut modifier ses conditions à tout moment. Migrer la chaîne CI/CD vers une forge auto-hébergée, c'est s'affranchir de cette incertitude. Woodpecker CI est conçu précisément pour cet usage : un moteur de pipeline léger, open source (Apache 2.0), qui s'installe aux côtés de Gitea ou Forgejo et ne connaît pas de compteur de minutes.

GitHub Actions runners vs Woodpecker CI auto-hébergé

CritèreGitHub Actions (runners cloud)Woodpecker CI sur VPS
Coût0,008 $ / min (Linux) + 0,002 $ / min orchestration sur dépôts privésInclus dans le coût fixe du VPS (à partir de `{{vps.start.price}}`)
RAM du moteur CIRunners GitHub-hosted : ressources mutualisées, non maîtriséesServeur + agent Woodpecker : moins de 50 Mo RAM cumulés
SouverainetéCode et secrets transitent par l'infrastructure GitHub/MicrosoftTout reste sur votre VPS — aucun transit externe
Syntaxe workflow`.github/workflows/*.yml` — standard très répandu`.woodpecker.yml` — syntaxe propre, plus courte, non compatible GitHub Actions
Prérequis forgeAucun (GitHub héberge le dépôt)Gitea ou Forgejo auto-hébergé (ou GitHub en forge distante)
LicencePropriétaireApache 2.0

Prérequis avant l'installation

Pour déployer Woodpecker CI dans de bonnes conditions, vérifiez les points suivants.

VPS : 1 vCPU et 1 Go de RAM suffisent pour le serveur Woodpecker, un agent et une forge Gitea ou Forgejo légère. Comptez 2 Go si vous lancez plusieurs builds en parallèle ou si vos jobs compilent des images Docker.

Logiciels : Docker et Docker Compose doivent être installés. Si vous partez d'un VPS vierge, le guide Démarrer avec Docker sur VPS couvre cette étape.

Forge git : Woodpecker CI s'appuie sur OAuth2 pour l'authentification. Il vous faut une instance Gitea ou Forgejo déjà en place et accessible via HTTPS (par exemple sur git.votre-domaine.com). Les guides Héberger Gitea et Héberger Forgejo détaillent cette installation.

Domaine : prévoyez un sous-domaine dédié à Woodpecker — par exemple ci.votre-domaine.com — pointant vers l'IP de votre VPS, avec le port 443 ouvert. Ce sous-domaine sert de WOODPECKER_HOST et d'URL de redirection OAuth2.

Installer Woodpecker CI avec Docker Compose

01

Créer une application OAuth2 dans Gitea

Dans Gitea, allez dans Paramètres → Applications → Gérer les applications OAuth2. Donnez un nom à l'application (par exemple woodpecker) et renseignez l'URL de redirection : https://ci.votre-domaine.com/authorize. Notez le Client ID et le Client Secret générés — vous en aurez besoin à l'étape suivante.

Si vous utilisez Forgejo, la procédure est identique : Paramètres → Applications → OAuth2.

02

Créer le fichier docker-compose.yml

Créez le répertoire /opt/woodpecker et placez-y un fichier docker-compose.yml avec les deux services — serveur et agent :

services:
  woodpecker-server:
    image: woodpeckerci/woodpecker-server:v3
    restart: always
    ports:
      - "8000:8000"
    volumes:
      - woodpecker-server-data:/var/lib/woodpecker/
    environment:
      - WOODPECKER_OPEN=false
      - WOODPECKER_HOST=https://ci.votre-domaine.com
      - WOODPECKER_GITEA=true
      - WOODPECKER_GITEA_URL=https://git.votre-domaine.com
      - WOODPECKER_GITEA_CLIENT=${WOODPECKER_GITEA_CLIENT}
      - WOODPECKER_GITEA_SECRET=${WOODPECKER_GITEA_SECRET}
      - WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}

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

volumes:
  woodpecker-server-data:
  woodpecker-agent-config:

Le serveur écoute en interne sur le port 8000 (interface web) et 9000 (gRPC, communication avec l'agent). N'exposez pas ces ports directement : un reverse proxy se charge du TLS.

03

Créer le fichier .env

Dans /opt/woodpecker, créez un fichier .env contenant les trois variables sensibles :

WOODPECKER_GITEA_CLIENT=<client-id-oauth2>
WOODPECKER_GITEA_SECRET=<client-secret-oauth2>
WOODPECKER_AGENT_SECRET=<chaine-aleatoire-longue>

Générez WOODPECKER_AGENT_SECRET avec openssl rand -hex 32. Cette chaîne authentifie l'agent auprès du serveur — ne la partagez pas.

04

Configurer le reverse proxy nginx

Placez Woodpecker derrière nginx avec un certificat Let's Encrypt. Exemple de bloc server pour ci.votre-domaine.com :

server {
    listen 443 ssl;
    server_name ci.votre-domaine.com;
    ssl_certificate /etc/letsencrypt/live/ci.votre-domaine.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ci.votre-domaine.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 https;
    }
}

Obtenez le certificat avec certbot certonly --nginx -d ci.votre-domaine.com puis rechargez nginx avec systemctl reload nginx.

05

Démarrer la stack

Depuis /opt/woodpecker, lancez :

docker compose up -d

Suivez les logs du serveur jusqu'à voir la ligne indiquant que le serveur est prêt :

docker compose logs -f woodpecker-server

Ouvrez https://ci.votre-domaine.com dans votre navigateur. La page de connexion affiche un bouton Se connecter via Gitea. Cliquez dessus : Gitea demande l'autorisation OAuth2, puis vous redirige vers le dashboard Woodpecker.

06

Activer un dépôt et déclencher le premier build

Dans le dashboard Woodpecker, cliquez sur + Ajouter un dépôt. La liste de vos dépôts Gitea s'affiche. Sélectionnez un projet et activez-le. Woodpecker enregistre automatiquement un webhook dans Gitea pour déclencher les builds à chaque push.

Poussez un premier commit sur ce dépôt : si le fichier .woodpecker.yml est présent à la racine, le pipeline se déclenche immédiatement dans l'interface.

Migration d'un workflow GitHub Actions vers .woodpecker.yml

Woodpecker CI a sa propre syntaxe YAML — elle n'est pas compatible GitHub Actions. La bonne nouvelle : elle est plus courte. Voici la migration d'un workflow Node.js classique.

Avant — .github/workflows/ci.yml :

name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm test

Après — .woodpecker.yml :

steps:
  - name: test
    image: node:20
    commands:
      - npm ci
      - npm test

Les différences clés : Woodpecker utilise directement une image Docker comme environnement d'exécution (pas besoin de setup-node), et chaque étape est déclarée comme un service de conteneur. L'action checkout est implicite — Woodpecker clone automatiquement le dépôt dans le workspace partagé entre les étapes.

Secrets de pipeline et variable WOODPECKER_SECRET

Ne mettez jamais de tokens, clés SSH ou mots de passe dans votre .woodpecker.yml versionné. Woodpecker gère les secrets au niveau du dépôt ou de l'organisation : dans le dashboard, ouvrez le dépôt → Paramètres → Secrets → Ajouter un secret. Chaque secret est injecté comme variable d'environnement au moment du build.

Pour utiliser un secret dans le pipeline :

steps:
  - name: deploy
    image: alpine
    environment:
      SSH_DEPLOY_KEY:
        from_secret: ssh_deploy_key
    commands:
      - echo "$SSH_DEPLOY_KEY" > /tmp/id_rsa
      - chmod 600 /tmp/id_rsa
      - ssh -i /tmp/id_rsa [email protected] ./deploy.sh

La syntaxe from_secret extrait la valeur depuis le coffre Woodpecker sans l'écrire dans les logs ni dans le fichier YAML.

Dépannage courant

L'agent n'apparaît pas dans le dashboard. Vérifiez que WOODPECKER_AGENT_SECRET est identique dans les deux services du docker-compose.yml. Si vous avez modifié le .env après le premier démarrage, relancez avec docker compose down && docker compose up -d.

La connexion OAuth2 échoue. L'URL de redirection enregistrée dans Gitea doit correspondre exactement à https://ci.votre-domaine.com/authorize. Une barre oblique finale, une faute d'orthographe ou un protocole HTTP au lieu de HTTPS suffisent à bloquer le flux OAuth2. Vérifiez également que WOODPECKER_GITEA_URL dans le docker-compose.yml pointe bien vers l'URL publique de votre Gitea — le conteneur Woodpecker doit pouvoir la résoudre depuis l'intérieur du réseau Docker.

Le webhook ne se déclenche pas. Ouvrez le dépôt dans Gitea → Paramètres → Webhooks et vérifiez que le webhook Woodpecker est bien présent et que les livraisons récentes n'ont pas d'erreur 4xx. Si l'URL de webhook pointe sur http:// au lieu de https://, Gitea peut refuser de l'appeler. Reconfigurez WOODPECKER_HOST avec l'URL complète en HTTPS et réactivez le dépôt dans Woodpecker pour forcer la mise à jour du webhook.

Les builds échouent par manque de mémoire. Le serveur et l'agent Woodpecker consomment moins de 50 Mo au repos — mais chaque étape de build lance un conteneur Docker supplémentaire. Sur un VPS à 1 Go, limitez les builds concurrents à 1 ou 2 en ajoutant WOODPECKER_MAX_PROCS=2 dans l'environnement du service woodpecker-agent.

Pour aller plus loin

Une fois le pipeline de base fonctionnel, plusieurs optimisations valent le détour.

Multi-runner. Ajoutez un second service woodpecker-agent dans votre docker-compose.yml (même image, même WOODPECKER_AGENT_SECRET) pour paralléliser les builds. Chaque agent est indépendant et peut tourner sur un VPS séparé si votre charge le justifie.

Cache Docker entre builds. Montez un volume Docker dans l'agent et activez le cache des layers Docker pour éviter de retélécharger les images à chaque build. Woodpecker supporte le cache de pipeline natif via le plugin woodpecker-ci/cache — ajoutez-le comme étape dédiée dans votre .woodpecker.yml.

Notifications. Woodpecker peut notifier un canal de messagerie à chaque build. Des plugins communautaires couvrent Matrix, Slack, Telegram et Mattermost — cherchez woodpecker-ci/notify-matrix ou appleboy/drone-telegram dans la documentation officielle.

Pipeline conditionnel. La syntaxe Woodpecker permet de restreindre une étape à une branche ou à un événement précis :

steps:
  - name: deploy
    image: alpine
    when:
      branch: main
      event: push
    commands:
      - ./deploy.sh

Pour approfondir la mise en place des pipelines, le guide Woodpecker CI et Forgejo : pipeline CI/CD sur VPS détaille les étapes avancées, notamment l'intégration Forgejo et les pipelines multi-étapes. Le guide Checklist Docker Compose en production couvre les bonnes pratiques pour sécuriser vos stacks Docker en production.

Un VPS ServOrbit pour votre pipeline CI/CD

Le plan `{{vps.start.name}}` à `{{vps.start.price}}` — 1 vCPU, 1 Go de RAM, IP fixe — suffit pour faire tourner Woodpecker CI, un agent et une forge Gitea en parallèle, sans compteur de minutes.

Besoin d'aide ?

Parcourez notre centre d'aide et notre FAQ, ou contactez notre équipe — rappel, WhatsApp ou e-mail. Support en français, anglais et arabe.

Écrire sur WhatsApps'ouvre dans un nouvel onglet