Guide de déploiement

Migrer sa CI/CD vers Gitea ou Forgejo : hors GitHub Actions

Déployer sur un VPS Cloud →

Automatisation11 min de lecture

Migrer sa CI/CD vers Gitea ou Forgejo : hors GitHub Actions

Depuis le 1er mars 2026, les minutes de CI sur les dépôts GitHub privés sont facturées à la consommation. Pour les équipes qui enchaînent les pipelines — tests, lint, build Docker, déploiement — la facture mensuelle peut rapidement dépasser le budget alloué à l'hébergement lui-même. Gitea et Forgejo permettent de reprendre le contrôle : même syntaxe YAML, même logique de runner, zéro coût de minute. Ce guide compare les deux options et détaille l'installation pas à pas sur un VPS.

Ce qui a changé dans la tarification GitHub Actions

Jusqu'en début d'année 2026, les dépôts privés sur GitHub bénéficiaient d'un quota mensuel de minutes incluses, selon le plan souscrit. Ce modèle a évolué : depuis le 1er mars 2026, GitHub a revu les seuils inclus à la baisse et a généralisé la facturation à la minute pour les runners Linux hébergés par GitHub sur les plans inférieurs à GitHub Team et GitHub Enterprise.

Les runners auto-hébergés (self-hosted), eux, n'ont jamais été facturés par GitHub — ils consomment vos propres ressources. C'est précisément ce levier que Gitea Actions et Forgejo Actions exploitent : en hébergeant votre forge sur un VPS, vous portez vos pipelines sur un runner que vous contrôlez, sans compteur GitHub.

L'argument n'est pas seulement financier. Les données de vos dépôts privés ne transitent plus par l'infrastructure GitHub. Les pipelines s'exécutent dans l'environnement réseau de votre choix — utile si votre déploiement cible un réseau privé ou un cluster interne. Et la forge reste accessible même en cas de panne ou de restriction externe.

Pourquoi migrer sa CI/CD vers une forge auto-hébergée

  • Coût variable supprimé — le runner tourne sur votre VPS, chaque minute de CI est une ressource déjà payée, pas une ligne de facturation supplémentaire.
  • Confidentialité des pipelines — le code source, les secrets d'environnement et les artefacts de build ne quittent pas votre infrastructure.
  • Compatibilité YAML.gitea/workflows/ci.yml suit la même syntaxe que .github/workflows/ci.yml ; la migration d'un pipeline existant ne demande le plus souvent qu'un déplacement de fichier.
  • Contrôle total des images de runner — vous choisissez les versions de PHP, Node, Python ou Docker sans dépendre du catalogue GitHub.
  • Forge légère — Gitea fonctionne avec 200 à 300 Mo de RAM pour les dépôts, act_runner consomme environ 50 Mo par job ; un VPS avec 1 Go de RAM suffit pour une petite équipe.
  • Indépendance de service — vos pipelines continuent à tourner quelle que soit la disponibilité ou la politique tarifaire de la plateforme upstream.
  • Gestion unifiée des accès — les permissions, les équipes et les webhooks vivent sur votre instance, sans délégation d'accès à un tiers.
  • Stockage des artefacts sous votre contrôle — les binaires, les images Docker et les rapports de couverture sont stockés là où vous le décidez.

Prérequis

Avant d'installer Gitea ou Forgejo, vérifiez que votre VPS répond aux critères suivants.

RAM : 1 Go minimum pour une petite forge (jusqu'à 5 développeurs, pipelines simples). Comptez 2 Go si vous activez plusieurs runners en parallèle ou si vos jobs compilent des images Docker.

CPU : 1 vCPU suffit pour la forge elle-même ; les jobs de CI consomment ce que vous leur accordez via la configuration du runner.

Stockage : 20 Go pour démarrer — les dépôts Git et les artefacts de pipeline grandissent vite selon votre activité.

Port public : le port 22 (SSH Git) ou un port alternatif, et le port 443 (HTTPS). Le port 3000 est utilisé en interne par Gitea/Forgejo ; il ne doit pas être exposé directement.

Domaine : un sous-domaine dédié (git.votredomaine.com) est fortement conseillé — les webhooks GitHub→Gitea, les clés SSH et les URLs de clonage s'appuient sur un nom stable.

Docker : Gitea et Forgejo se déploient proprement via Docker Compose, qui simplifie les mises à jour et l'isolation des processus.

Gitea Actions vs Forgejo Actions vs Woodpecker CI

CritèreGitea ActionsForgejo ActionsWoodpecker CI
OrigineFork de Gogs, ~47 000 étoiles GitHub, licence MITHard-fork de Gitea depuis déc. 2022, piloté par Codeberg, licence AGPL-3.0CI externe, open-source, fonctionne avec Gitea/Forgejo/GitHub
Runneract_runner (même binaire)act_runner (même binaire, version Forgejo)Agent Woodpecker dédié (woodpecker-agent)
Syntaxe workflowCompatible `.github/workflows/*.yml`Compatible `.github/workflows/*.yml`Syntaxe YAML propre, non compatible GitHub Actions
Effort de migrationDéplacer le fichier YAML dans `.gitea/workflows/`Déplacer le fichier YAML dans `.gitea/workflows/`Réécrire les workflows dans le format Woodpecker
GouvernanceSociété commerciale (Gitea Ltd)Collectif de contributeurs indépendants (Codeberg e.V.)Communauté, sans entité commerciale derrière
Consommation mémoire forge~200-300 Mo RAM repos~200-300 Mo RAM reposNécessite aussi une forge (Gitea/Forgejo) en plus
Mises à jourReleases fréquentes, canal stable disponibleReleases alignées sur Gitea + correctifs propresCycle de release indépendant
Cas d'usage principalForge légère avec CI intégrée, migration depuis GitHubForge légère, CI intégrée, préférence pour la gouvernance libreCI autonome avancée, pipelines multi-étapes complexes

Option A : Gitea avec act_runner

Gitea est un fork de Gogs maintenu activement depuis 2016, aujourd'hui à environ 47 000 étoiles sur GitHub sous licence MIT. Il embarque depuis la version 1.19 un moteur d'Actions compatible avec la syntaxe GitHub Actions, piloté par act_runner.

Installation de Gitea et du runner

01

Créer le fichier Docker Compose

Créez un répertoire de travail et un fichier docker-compose.yml :

services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__actions__ENABLED=true
    volumes:
      - ./gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
    restart: unless-stopped

Activez GITEA__actions__ENABLED=true dès le départ — sans cette variable, l'onglet Actions n'apparaît pas dans l'interface.

02

Lancer Gitea et compléter l'installation initiale

Démarrez le conteneur puis ouvrez http://<votre-ip>:3000 dans un navigateur. L'assistant d'installation vous demande le type de base de données (SQLite suffit pour une petite forge), le nom du serveur et l'URL externe. Saisissez l'URL HTTPS que vous allez configurer (https://git.votredomaine.com) — elle est écrite dans la configuration et sert de base pour les URLs de clonage et les webhooks.

Créez le compte administrateur depuis cet assistant.

03

Configurer le reverse proxy et le TLS

Placez Gitea derrière nginx avec un certificat Let's Encrypt. Exemple de bloc server :

server {
    listen 443 ssl;
    server_name git.votredomaine.com;
    ssl_certificate /etc/letsencrypt/live/git.votredomaine.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/git.votredomaine.com/privkey.pem;
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Obtenez le certificat avec certbot certonly --nginx -d git.votredomaine.com puis rechargez nginx.

04

Créer un token runner dans Gitea

Connectez-vous à votre instance Gitea en tant qu'administrateur. Allez dans Administration du site → Runners → Créer un runner. Copiez le token affiché — il sera utilisé à l'étape suivante pour enregistrer act_runner.

05

Déployer act_runner

Ajoutez le service act_runner à votre docker-compose.yml :

  act_runner:
    image: gitea/act_runner:latest
    container_name: act_runner
    environment:
      - GITEA_INSTANCE_URL=https://git.votredomaine.com
      - GITEA_RUNNER_REGISTRATION_TOKEN=<votre-token>
      - GITEA_RUNNER_NAME=vps-runner
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./runner-data:/data
    restart: unless-stopped
    depends_on:
      - gitea

Relancez avec docker compose up -d. Le runner apparaît dans l'interface Gitea sous Administration du site → Runners avec le statut Idle.

06

Pousser un workflow de test

Dans l'un de vos dépôts Gitea, créez le fichier .gitea/workflows/ci.yml :

name: CI
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Vérification
        run: echo "Pipeline actif sur Gitea Actions"

Poussez un commit. Le job apparaît dans l'onglet Actions du dépôt et s'exécute sur votre runner VPS.

Option B : Forgejo avec act_runner

Forgejo est un hard-fork de Gitea initié en décembre 2022 par la communauté Codeberg, distribuée sous licence AGPL-3.0. Il partage la même syntaxe de workflow et le même binaire act_runner, avec une gouvernance communautaire et un cycle de correctifs indépendant. Pour les équipes sensibles aux questions de gouvernance ou de licence, Forgejo est l'alternative directe à Gitea — l'expérience utilisateur et la compatibilité YAML sont identiques.

Différences d'installation par rapport à Gitea

01

Remplacer l'image Docker

Dans votre docker-compose.yml, remplacez l'image Gitea par l'image Forgejo officielle :

services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:latest
    container_name: forgejo
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - FORGEJO__actions__ENABLED=true
    volumes:
      - ./forgejo-data:/data
    ports:
      - "3000:3000"
      - "222:22"
    restart: unless-stopped

La variable d'environnement passe de GITEA__ à FORGEJO__ pour les paramètres propres à Forgejo.

02

Utiliser le runner Forgejo

Forgejo maintient sa propre version de act_runner. Utilisez l'image publiée sur le registre Codeberg :

  act_runner:
    image: code.forgejo.org/forgejo/runner:latest
    container_name: forgejo_runner
    environment:
      - FORGEJO_INSTANCE_URL=https://git.votredomaine.com
      - FORGEJO_RUNNER_REGISTRATION_TOKEN=<votre-token>
      - FORGEJO_RUNNER_NAME=vps-runner
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./runner-data:/data
    restart: unless-stopped
03

Récupérer le token runner dans Forgejo

La procédure est identique à Gitea : Administration du site → Runners → Créer un runner. Le token est à usage unique — notez-le avant de fermer la page.

04

Placer vos workflows dans `.gitea/workflows/`

Forgejo lit les fichiers de workflow dans le même répertoire que Gitea : .gitea/workflows/. Un workflow écrit pour GitHub Actions ou Gitea Actions fonctionne sans modification. La seule contrainte : l'action actions/checkout@v4 et ses cousines sont résolues par le cache d'actions de votre instance — la première exécution les télécharge, les suivantes les réutilisent.

Compatibilité YAML avec GitHub Actions

Le point de compatibilité le plus souvent sous-estimé : .gitea/workflows/ci.yml et .github/workflows/ci.yml partagent la même grammaire. Les événements déclencheurs (push, pull_request, schedule), les jobs, les steps, les matrices et les conditions if: fonctionnent de la même manière.

Un workflow GitHub typique :

name: Tests
on:
  push:
    branches: [main, dev]
  pull_request:

jobs:
  phpunit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.4'
      - run: composer install --no-interaction
      - run: vendor/bin/phpunit

Ce fichier, copié dans .gitea/workflows/ci.yml, s'exécute tel quel sur Gitea Actions ou Forgejo Actions. Les actions du marketplace GitHub (actions/checkout, shivammathur/setup-php, etc.) sont téléchargées depuis GitHub lors de la première exécution et mises en cache localement.

Limite à connaître : certaines actions propriétaires ou spécifiques à GitHub (OIDC, CodeQL, Dependabot) n'ont pas d'équivalent direct et doivent être remplacées par des alternatives open source ou des scripts shell.

Avantages comparatifs d'un runner self-hosted

  • Coût fixe et prévisible — vous ne payez que le VPS, quelle que soit la fréquence de vos pipelines.
  • Confidentialité — le code source, les variables d'environnement et les artefacts de build ne transitent pas par un service tiers.
  • Personnalisation du runner — installez les dépendances système, les outils spécifiques à votre stack ou les images Docker privées directement sur le runner.
  • Réseau interne accessible — un job peut atteindre une base de données de staging ou un registry Docker privé sur votre réseau sans exposition publique.
  • Déploiements sans transit réseau — le runner s'exécute dans le même datacenter que votre serveur cible ; les artefacts de build sont copiés localement, sans traverser les serveurs GitHub.
  • Archivage sous votre contrôle — les logs de pipeline et les artefacts sont conservés aussi longtemps que vous le décidez, sans limite imposée par la plateforme.

Durcissement de l'installation

Un runner auto-hébergé expose votre infrastructure si sa configuration est laxiste. Trois points à vérifier avant de mettre votre instance en production.

Premier point : n'exposez pas l'interface d'administration Gitea/Forgejo sur Internet. Placez-la derrière le reverse proxy avec authentification à deux facteurs activée et, si possible, une restriction par IP ou un VPN pour l'accès admin.

Deuxième point : le token du runner est à usage unique et doit rester secret. Une fois le runner enregistré, le token n'a plus de valeur — mais s'il fuite avant enregistrement, un tiers peut créer un runner malveillant sur votre instance.

Troisième point : isolez le runner dans un réseau Docker dédié, séparé de la forge. Un job compromis ne doit pas pouvoir atteindre le conteneur Gitea/Forgejo via le réseau interne Docker. Déclarez deux réseaux dans votre docker-compose.yml et n'accordez au runner que l'accès à Internet et à ce qui est nécessaire à vos pipelines.

Dépannage — erreurs fréquentes

Le runner reste en statut « Offline » après démarrage. Vérifiez que GITEA_INSTANCE_URL (ou FORGEJO_INSTANCE_URL) pointe vers l'URL HTTPS publique de votre forge, pas vers localhost ou l'IP interne. Le runner se connecte de l'extérieur du conteneur.

L'onglet Actions n'apparaît pas dans l'interface. La variable GITEA__actions__ENABLED=true (ou FORGEJO__actions__ENABLED=true) doit être présente au démarrage du conteneur. Un simple redémarrage sans cette variable ne suffit pas — arrêtez le conteneur, ajoutez la variable, puis relancez avec docker compose up -d.

L'action actions/checkout@v4 échoue avec une erreur de résolution. Gitea et Forgejo tentent de télécharger les actions depuis GitHub lors de la première exécution. Si votre VPS ne peut pas atteindre github.com, configurez un miroir local d'actions dans la section [actions] de app.ini avec la clé DEFAULT_ACTIONS_URL.

Le job démarre puis s'arrête immédiatement avec « exit code 137 ». C'est un signal OOM (Out Of Memory) du noyau. L'image de runner (ubuntu-latest) charge plusieurs outils en mémoire. Augmentez la RAM disponible sur votre VPS ou réduisez le parallélisme (max_parallel_jobs dans la configuration du runner) pour éviter plusieurs jobs simultanés sur un hôte sous-dimensionné.

Reprendre le contrôle de votre CI/CD

Gitea et Forgejo offrent le même niveau de compatibilité avec vos workflows GitHub Actions existants, avec des profils de gouvernance différents — MIT pour Gitea, AGPL-3.0 et collectif indépendant pour Forgejo. Dans les deux cas, act_runner s'installe en quelques minutes sur un VPS standard, et vos pipelines migrent sans réécriture.

Si vous utilisez déjà un template VPS Gitea sur ServOrbit, le runner peut tourner sur la même instance ou sur un VPS dédié selon la charge de vos pipelines. Le guide détaillé d'installation de Gitea est disponible à la suite — il couvre les options de stockage, la configuration SMTP et la sauvegarde automatisée.

Pour déployer Gitea sur un VPS en quelques minutes, consultez notre guide : Héberger Gitea sur VPS.

Déployez votre forge Git sur VPS

Gitea est disponible comme template VPS sur ServOrbit. Votre instance est opérationnelle en quelques minutes, avec Docker, nginx et un certificat TLS préconfigurés. Ajoutez `act_runner` et vos pipelines tournent sur votre infrastructure dès la première heure.

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.