Pourquoi choisir Forgejo pour votre forge Git auto-hébergée
Forgejo est né en 2022 d'un fork de Gitea, motivé par des inquiétudes sur la gouvernance du projet. Son développement est entièrement communautaire, sous licence GPLv3+ depuis la v9.0 (août 2024 ; MIT auparavant), sans dépendance à une société commerciale. Pour les équipes qui veulent contrôler leur code source, leur pipeline CI/CD et leurs artefacts sans passer par GitHub, GitLab ou Bitbucket, Forgejo est l'une des solutions les plus légères. L'interface est familière pour tout développeur ayant utilisé GitHub, la migration depuis Gitea est transparente et la compatibilité avec les GitHub Actions simplifie l'adoption.
Bénéfices concrets d'un Forgejo auto-hébergé
- Souveraineté totale : votre code ne quitte jamais votre infrastructure
- Compatible GitHub Actions via Forgejo Actions — réutilisez vos workflows existants
- Empreinte mémoire faible : un petit VPS suffit à une petite équipe
- Registre de paquets intégré : npm, PyPI, Maven, Helm, container OCI
- Pas de limite sur le nombre de dépôts privés ni de collaborateurs
- Fédération ActivityPub en cours de standardisation — interopérabilité future avec d'autres forges
- Licences OSS, auditable, sans surprise de tarification
- Mises à jour maîtrisées : vous choisissez quand migrer
Prérequis matériels et logiciels chiffrés
Avant de lancer Forgejo, dimensionnez votre VPS selon la taille réelle de votre équipe. Pour 1 à 5 développeurs avec quelques dizaines de dépôts, 1 vCPU et 1 Go de RAM suffisent. Pour 5 à 20 développeurs avec CI/CD active, prévoyez 2 vCPU et 2 Go de RAM. Au-delà de 20 développeurs ou pour des dépôts de grande taille (monorepos, binaires), 4 vCPU et 4 Go de RAM garantissent une expérience fluide. Côté stockage, comptez le volume de vos dépôts Git plus 20 % de marge pour les artefacts et les sauvegardes.
Sur le plan réseau, trois ports doivent être ouverts dans votre pare-feu : le port 80 (HTTP, pour la validation Let's Encrypt), le port 443 (HTTPS, trafic web) et le port 2222 (SSH Git, pour éviter le conflit avec le SSH d'administration sur 22). Côté logiciel, vous avez besoin de Docker Engine ≥ 24, Docker Compose v2 et d'un nom de domaine pointant vers votre VPS.
Déployer Forgejo avec Docker et SSL
Préparer l'environnement
Créez les répertoires qui persisteront les données hors du conteneur :
mkdir -p /opt/forgejo/{data,config,db} chown -R 1000:1000 /opt/forgejoCréez le fichier
/opt/forgejo/.envavec vos valeurs :FORGEJO_DOMAIN=git.mondomaine.com FORGEJO_SSH_PORT=2222Ajoutez-y un mot de passe de base de données généré, jamais un mot de passe d'exemple, puis protégez le fichier :
echo "POSTGRES_PASSWORD=$(openssl rand -hex 32)" >> /opt/forgejo/.env chmod 600 /opt/forgejo/.envCréer le docker-compose.yml
services: forgejo: image: codeberg.org/forgejo/forgejo:17 restart: unless-stopped environment: - USER_UID=1000 - USER_GID=1000 - FORGEJO__database__DB_TYPE=postgres - FORGEJO__database__HOST=db:5432 - FORGEJO__database__NAME=forgejo - FORGEJO__database__USER=forgejo - FORGEJO__database__PASSWD=${POSTGRES_PASSWORD} volumes: - /opt/forgejo/data:/data ports: - "127.0.0.1:3000:3000" - "${FORGEJO_SSH_PORT:-2222}:22" depends_on: - db db: image: postgres:16-alpine restart: unless-stopped environment: - POSTGRES_DB=forgejo - POSTGRES_USER=forgejo - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} volumes: - /opt/forgejo/db:/var/lib/postgresql/dataDémarrer les services
cd /opt/forgejo docker compose up -d docker compose logs -f forgejoAttendez que les logs indiquent que le serveur web écoute sur le port 3000. Forgejo effectue ses migrations de schéma automatiquement au premier démarrage.
Configurer le reverse proxy et SSL avec Caddy
Caddy est le choix le plus simple pour obtenir un certificat Let's Encrypt automatique. Installez-le puis créez
/etc/caddy/Caddyfile:git.mondomaine.com { reverse_proxy localhost:3000 }Démarrez Caddy :
systemctl enable --now caddy. Le certificat TLS est émis et renouvelé automatiquement. Si vous préférez nginx, configurez un blocproxy_pass http://127.0.0.1:3000;classique avec Certbot.Finaliser la configuration de l'instance
Ouvrez
https://git.mondomaine.comdans votre navigateur. L'assistant de configuration s'affiche une seule fois. Renseignez le domaine, l'URL SSH (ssh://git.mondomaine.com:2222), l'adresse e-mail de l'administrateur et désactivez l'inscription publique dès cet écran si votre forge est à usage privé. Une fois l'assistant validé, la configuration est verrouillée dans/opt/forgejo/data/gitea/conf/app.ini.Installer un runner Forgejo Actions
Le runner exécute le code de vos workflows : installez-le de préférence sur une machine dédiée. Dans *Administration du site → Actions → Runners* (
/admin/actions/runners), cliquez sur *Créer un nouveau runner* : Forgejo affiche un UUID et un jeton. Générez le fichier de configuration (docker run --rm data.forgejo.org/forgejo/runner:13 forgejo-runner generate-config > data/runner-config.yml), recopiez l'URL de l'instance, l'UUID et le jeton dans la sectionserver.connections, et déclarez vos labels (par exempleubuntu-latest:docker://node:20) dans la sectionrunner. Déployez ensuite le runner avec un démon Docker dédié (docker-in-docker) plutôt qu'en montant/var/run/docker.sockde l'hôte, qui donnerait à chaque job un accès root au serveur :services: docker-in-docker: image: docker:dind privileged: true command: ["dockerd", "-H", "tcp://0.0.0.0:2375", "--tls=false"] restart: unless-stopped runner: image: data.forgejo.org/forgejo/runner:13 depends_on: - docker-in-docker environment: DOCKER_HOST: tcp://docker-in-docker:2375 user: "1001:1001" volumes: - ./data:/data command: forgejo-runner daemon --config runner-config.yml restart: unless-stoppedLe port 2375 du démon docker-in-docker reste sur le réseau interne de Compose : ne le publiez jamais. Le runner apparaît dans l'interface dès qu'il se connecte. Chaque label choisit le mode d'exécution : docker:// (conteneur, recommandé), lxc:// (conteneur LXC) ou host (directement sur la machine, sans aucune isolation : à réserver à des tâches de confiance).
Écrire vos premiers workflows Forgejo Actions
La compatibilité avec la syntaxe GitHub Actions est très large. Créez le fichier .forgejo/workflows/ci.yml à la racine de votre dépôt :
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: |
npm ci
npm testLes labels runs-on correspondent aux labels déclarés lors de l'enregistrement du runner. Vous pouvez définir plusieurs runners avec des labels différents (ex. arm64, gpu, high-memory) et cibler le bon environnement par job. Les artefacts et le cache fonctionnent avec les mêmes actions officielles que sur GitHub.
Sécurité post-installation : les réglages essentiels
Un Forgejo fraîchement installé est fonctionnel mais pas durci. Voici les six points à traiter impérativement avant d'ouvrir la forge à votre équipe.
Désactiver l'inscription publique. Si vous ne l'avez pas fait dans l'assistant, ajoutez FORGEJO__service__DISABLE_REGISTRATION=true aux variables d'environnement du conteneur (ou DISABLE_REGISTRATION = true dans la section [service] de app.ini) : seul un administrateur peut alors créer des comptes. Sur une forge interne, personne ne doit pouvoir créer un compte sans invitation.
Activer la 2FA pour les administrateurs. Chaque compte admin doit activer l'authentification à deux facteurs dans *Paramètres → Sécurité*. Pour l'imposer, réglez GLOBAL_TWO_FACTOR_REQUIREMENT dans la section [security] de app.ini (admin pour les administrateurs, all pour tous les utilisateurs). Le paramètre REQUIRE_SIGNIN_VIEW, lui, oblige seulement à se connecter pour consulter la forge.
SSH par clé uniquement. Désactivez l'authentification par mot de passe dans /etc/ssh/sshd_config du serveur hôte (PasswordAuthentication no). Pour le SSH Git (port 2222), Forgejo n'accepte que les clés publiques enregistrées dans les profils utilisateurs — c'est son comportement par défaut.
Secrets de webhooks. Lors de la création de chaque webhook (vers votre CI externe, Slack, etc.), renseignez toujours le champ *Secret*. Forgejo signe la charge utile avec HMAC-SHA256 ; votre récepteur doit vérifier cette signature avant de traiter l'événement.
Packages privés. Si vous utilisez le registre de paquets intégré, rappelez-vous qu'un paquet hérite de la visibilité de son propriétaire : publiez-le sous une organisation ou un compte privé pour le réserver à ses membres. Les tokens d'accès pour publier doivent avoir une portée minimale (write:package uniquement, jamais un token admin global).
Pare-feu. Fermez tous les ports sauf 80, 443 et 2222. Le port 3000 (Forgejo interne) ne doit jamais être exposé directement ; il est consommé uniquement par le reverse proxy en loopback, d'où sa publication sur 127.0.0.1:3000 dans le compose. Un port publié par Docker contourne les règles ufw : seule cette liaison à 127.0.0.1 le garde hors d'Internet.
Mettre à jour Forgejo sans interruption
La procédure de mise à jour Docker est simple et ne nécessite que quelques secondes d'indisponibilité.
cd /opt/forgejo
# 1. Tirer la nouvelle image
docker compose pull forgejo
# 2. Sauvegarder la base avant toute migration
docker compose exec db pg_dump -U forgejo forgejo > backup-$(date +%Y%m%d).sql
# 3. Redémarrer le service
docker compose up -d forgejo
# 4. Vérifier les migrations de schéma
docker compose logs forgejo | grep -i migratForgejo exécute ses migrations automatiquement au démarrage. Vérifiez que les logs ne signalent aucune erreur de migration. En cas d'erreur de migration, restaurez la sauvegarde SQL et signalez le problème sur le tracker Forgejo. Le tag 17 ne suit que les versions 17.x : pour passer à la version majeure suivante, changez le tag dans le compose après une sauvegarde complète, et consultez les notes de version avant chaque saut de version majeure. Forgejo refuse de démarrer sur une base plus récente que lui : le retour arrière passe par la restauration de la sauvegarde.
Migrer depuis Gitea en cinq minutes
Forgejo est un fork direct de Gitea : la mise à niveau depuis Gitea est prise en charge jusqu'à la version 1.22 incluse, en passant d'abord par Forgejo v10.0.x. Pour migrer, arrêtez Gitea, copiez son répertoire de données (/data ou /opt/gitea) vers /opt/forgejo/data, remplacez l'image par codeberg.org/forgejo/forgejo:10 dans votre docker-compose et redémarrez, puis montez vers la version actuelle. Forgejo détecte automatiquement le schéma Gitea et applique ses propres migrations. Vos dépôts, utilisateurs, clés SSH, webhooks et issues sont intégralement conservés. Les versions de Gitea postérieures à 1.22 ne sont pas couvertes par le guide de mise à niveau officiel de Forgejo : ne tentez pas la bascule directe.
Dépannage : les erreurs les plus fréquentes
Connexion SSH refusée sur le port 2222. Vérifiez d'abord que le port est bien publié par Docker (docker compose ps → colonne Ports). Ensuite, testez depuis le client : ssh -p 2222 [email protected]. Si la réponse est PTY allocation request failed, la connexion fonctionne — Forgejo répond Hi <utilisateur>! You've successfully authenticated. Si vous obtenez Connection refused, le pare-feu bloque le port : ufw allow 2222/tcp.
Runner affiché offline dans l'interface. Le runner contacte Forgejo en HTTPS sortant. Vérifiez que le conteneur runner peut résoudre et atteindre git.mondomaine.com. Un certificat auto-signé nécessite de monter votre CA dans le conteneur. Redémarrez le runner après avoir corrigé la connectivité : docker compose restart runner.
Push rejeté par un hook pre-receive. Forgejo peut rejeter un push si un hook de protection de branche est actif (revue de code requise, tests CI obligatoires) ou si une règle de taille de fichier est dépassée. Le message d'erreur git contient le détail. Pour les gros binaires (> 100 Mo), utilisez Git LFS : Forgejo supporte le protocole LFS nativement.
Interface lente après plusieurs mois. Lancez le garbage collector Git sur les dépôts actifs depuis l'administration : *Administration du site → Tableau de bord → Opérations de maintenance*, tâche de nettoyage (garbage collection) des dépôts. Pour automatiser, activez la tâche planifiée [cron.git_gc_repos] dans app.ini (ENABLED = true ; elle tourne toutes les 72 h par défaut).
Fédération ActivityPub : ce que Forgejo prépare
Forgejo développe la fédération entre forges avec ForgeFed, une extension du protocole ActivityPub (le même que Mastodon). Elle reste expérimentale et désactivée par défaut ([federation] ENABLED = false) : la modération et le contrôle d'accès ne sont pas encore développés, et le projet prévient qu'un changement incompatible peut « brûler » le domaine de l'instance pour toute fédération future. Ne l'activez pas sur une forge de production. La fédération complète — fork cross-instance, pull request inter-forge — est en cours de standardisation au sein du groupe ForgeFed. Si vos collaborateurs sont sur des forges différentes, cette évolution permettra à terme de contribuer sans créer de compte sur chaque instance.
Forgejo vs Gitea vs GitLab CE : choisir sa forge
Faites défiler le tableau
| Critère | Forgejo | Gitea | GitLab CE |
|---|---|---|---|
| Gouvernance | Communauté (Codeberg e.V.) | Société commerciale (CommitGo) | Société commerciale (GitLab Inc) |
| RAM minimale | Faible (petit VPS) | Faible (petit VPS) | 8 Go (16 Go conseillés) |
| Compatibilité GitHub Actions | Oui (Forgejo Actions) | Oui (Gitea Actions) | Non (GitLab CI, syntaxe propre) |
| Registre de paquets | Oui (multi-format) | Oui | Oui |
| Fédération ActivityPub | En cours (ForgeFed) | Non | Non |
| Migration depuis GitHub | Oui (miroir + import) | Oui | Oui |
| Interface d'administration | Simple, intégrée | Simple, intégrée | Complète mais lourde |
| Licence | GPLv3+ (depuis v9.0) | MIT | MIT (CE) / EE (payant) |
| Fréquence des releases | Trimestrielle (+ LTS) | Plusieurs par an | Mensuelle |