Offre Durée limitée : -10% sur tout le site* avec le code ELYPSEWELCOME10

Installer Forgejo ou Gitea sur un VPS Linux et le sécuriser

Mis à jour le 15 novembre 2026 8 min de lecture 11 sections

Auto-héberger ses dépôts Git donne la maîtrise des données, des accès et des sauvegardes. Forgejo et Gitea sont deux forges légères, écrites en Go, qui offrent dépôts, tickets, pull requests, registre de paquets et intégration continue. Ce guide installe Forgejo avec Docker Compose sur un VPS Linux, derrière Nginx et HTTPS, puis détaille les réglages de sécurité à ne pas oublier. Les commandes valent aussi pour Gitea, avec les adaptations signalées.

Forgejo ou Gitea : de quoi parle-t-on ?

Une forge logicielle héberge des dépôts Git et les outils qui tournent autour : revue de code, suivi des tickets, webhooks, actions de CI. Forgejo est un fork de Gitea. Les deux partagent la même architecture : un binaire unique, un fichier de configuration app.ini, une base de données (SQLite, MySQL/MariaDB ou PostgreSQL) et un dossier de données contenant les dépôts.

Pour un admin, la différence se joue sur la gouvernance du projet, le calendrier de publication et les fonctionnalités. Vérifiez la documentation officielle de celui que vous retenez avant de déployer : documentation Forgejo ou documentation Gitea.

Prérequis et dimensionnement

Une forge pour une petite équipe tourne sur un petit VPS. La charge vient surtout des opérations Git, du CI éventuel et de l'indexation. Il vous faut :

Prévoyez de l'espace disque pour la croissance des dépôts, des pièces LFS et des paquets. Les offres ElypseCloud reposent sur du SSD.

Binaire ou Docker ?

La documentation Forgejo propose une installation par binaire : copie dans /usr/local/bin, utilisateur système git, données dans /var/lib/forgejo, configuration dans /etc/forgejo et service systemd. Elle convient si vous voulez zéro conteneur. Docker apporte des mises à jour simples (changement de tag), un isolement et un déploiement reproductible. C'est la voie retenue ici.

Installer Forgejo avec Docker Compose

Créez un dossier de projet et le fichier Compose. L'exemple s'inspire de celui de la documentation officielle, avec deux durcissements : les ports web sont liés à 127.0.0.1 (seul Nginx les atteint) et la version est épinglée sur la série majeure.

mkdir -p /opt/forgejo && cd /opt/forgejo
nano compose.yml
services:
  server:
    image: codeberg.org/forgejo/forgejo:17
    container_name: forgejo
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - FORGEJO__service__DISABLE_REGISTRATION=true
    restart: always
    volumes:
      - ./forgejo:/data
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "127.0.0.1:3000:3000"
      - "222:22"

Points à retenir :

  • Le tag 17 suit les mises à jour mineures de la série 17. La documentation précise qu'un changement de version majeure exige une intervention manuelle : lisez les notes de version avant.
  • Le dossier ./forgejo doit appartenir à l'UID et au GID indiqués : chown -R 1000:1000 forgejo après sa création.
  • Les variables FORGEJO__SECTION__CLE écrasent ou ajoutent des valeurs dans app.ini. Elles ne peuvent pas supprimer une valeur déjà présente : il faut alors éditer le fichier. Sous Gitea, le principe est le même avec le préfixe GITEA__ et l'image gitea/gitea.
  • Le port 222 de l'hôte mène au SSH intégré du conteneur, utilisé uniquement pour les opérations Git. Il ne remplace pas le SSH d'administration du VPS.
mkdir -p forgejo && chown -R 1000:1000 forgejo
docker compose up -d
docker compose logs -f server

Au premier lancement, l'assistant d'installation est disponible sur le port 3000. Comme il n'écoute que sur le loopback, ouvrez un tunnel SSH vers le VPS et visitez http://localhost:3000 depuis votre poste. Cela évite d'exposer une page d'installation non protégée sur Internet.

Renseigner l'assistant

  • Base de données : SQLite pour démarrer. Pour une équipe plus large, PostgreSQL (voir installer PostgreSQL et sécuriser l'accès) ou MariaDB.
  • Domaine du serveur : git.exemple.fr.
  • URL de base : https://git.exemple.fr/. Une URL erronée casse les liens de clonage et les webhooks.
  • Port SSH publié : 222 pour que les URL de clonage soient correctes.
  • Compte administrateur : créez-le ici, avec un mot de passe long et unique.

Publier derrière Nginx en HTTPS

Ne publiez jamais le port 3000 en clair. Placez un reverse proxy devant, comme décrit dans Nginx en reverse proxy sur un VPS Linux. Voici un bloc minimal :

server {
    listen 80;
    server_name git.exemple.fr;

    client_max_body_size 512M;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

La directive client_max_body_size évite les erreurs 413 lors d'un push volumineux ou d'un envoi LFS. Adaptez la valeur à vos besoins. Obtenez ensuite le certificat avec Certbot (Certbot et Let's Encrypt sur un VPS Linux), puis vérifiez le résultat : publier un service en HTTPS détaille la démarche complète.

nginx -t && systemctl reload nginx
certbot --nginx -d git.exemple.fr

Sécuriser Forgejo : les réglages essentiels

Les paramètres se trouvent dans forgejo/gitea/conf/app.ini à l'intérieur du volume de données (le chemin exact dépend de l'image : vérifiez-le dans votre dossier monté). Après modification, redémarrez : docker compose restart.

Fermer les inscriptions

Par défaut, DISABLE_REGISTRATION vaut false dans la section [service] : n'importe qui peut ouvrir un compte sur une instance publique, et les forges ouvertes attirent le spam et le minage sauvage via le CI. Notre compose le passe à true. Créez ensuite vos utilisateurs depuis l'administration du site.

[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW  = true

REQUIRE_SIGNIN_VIEW (défaut false) impose la connexion même pour consulter les dépôts. Utile pour une forge purement interne.

Protéger le fichier de configuration

app.ini contient des secrets (clés internes, accès à la base). Pendant l'installation, il doit être modifiable ; ensuite, la documentation conseille de restreindre ses droits (640, répertoire en 750 pour l'installation binaire). Le paramètre INSTALL_LOCK de la section [security], défaut false, est positionné à true par l'assistant : vérifiez qu'il l'est, sinon la page d'installation reste accessible.

Comptes et authentification

  • Activez l'authentification à deux facteurs sur le compte administrateur et chez tous les utilisateurs.
  • Privilégiez les clés SSH et les jetons d'accès à portée limitée plutôt que les mots de passe pour Git.
  • Si vous disposez d'un SSO, voir Keycloak en SSO sur un VPS Linux pour centraliser les comptes.
  • Gardez un seul compte administrateur nominatif par personne, pas de compte partagé.

Limiter l'exposition du SSH de Git

Le champ SSH_PORT de [server] indique le port annoncé dans les URL de clonage ; START_SSH_SERVER (défaut false) active le serveur SSH intégré, ce qui n'est pas nécessaire ici puisque l'image Docker embarque déjà le sien. Si personne n'a besoin du clonage SSH depuis Internet, supprimez la ligne "222:22" du compose et n'utilisez que HTTPS.

Pare-feu et protection contre la force brute

N'ouvrez que le nécessaire : SSH d'administration, 80, 443 et, si besoin, 222. Avec UFW :

ufw default deny incoming
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 222/tcp
ufw enable

Attention : Docker publie ses ports en manipulant iptables et peut contourner les règles UFW pour les ports qu'il expose. C'est pourquoi on lie le port 3000 à 127.0.0.1 dans le compose. Pour un pare-feu plus fin, voir nftables sur un VPS Linux et ouvrir des ports avec UFW.

Ajoutez Fail2ban sur le SSH d'administration, et surveillez les échecs de connexion à Forgejo dans les journaux du conteneur. Pour une détection plus large, voir CrowdSec sur un VPS Linux. Pensez que, derrière un reverse proxy, l'adresse source vue par l'application est celle du proxy si les en-têtes ne sont pas pris en compte.

Sauvegarder et restaurer

Un dépôt perdu est un travail perdu. Les sauvegardes ElypseCloud sont une option : ne comptez pas dessus sans l'avoir souscrite, et conservez de toute façon une copie hors du VPS. À sauvegarder :

  • le dossier /opt/forgejo/forgejo (dépôts, configuration, pièces jointes, SQLite le cas échéant) ;
  • un dump de la base si vous utilisez PostgreSQL ou MariaDB ;
  • votre compose.yml et la configuration Nginx.
cd /opt/forgejo
docker compose stop
tar czf /root/forgejo-$(date +%F).tar.gz forgejo compose.yml
docker compose start

Transférez ensuite l'archive avec rsync vers un serveur distant et chiffrez-la, voir chiffrer ses sauvegardes hors site. Testez la restauration sur une machine vierge.

Mises à jour

Une forge exposée à Internet doit être tenue à jour : les failles Git et celles des plateformes de forge sont régulièrement corrigées, comme le montre la faille de clonage de sous-modules dans Git. Procédure :

  1. Lire les notes de version sur le site de Forgejo ou de Gitea.
  2. Faire une sauvegarde complète.
  3. Exécuter docker compose pull && docker compose up -d.
  4. Contrôler les journaux et tester un clone et un push.

Évitez le tag latest. Pour les montées de version majeure, la documentation Forgejo indique une opération manuelle : changez le tag volontairement, jamais par surprise. Pensez aussi à tenir à jour le système hôte, voir automatiser les mises à jour de sécurité sur Ubuntu.

Récapitulatif des réglages

SujetRéglageValeur recommandée
Inscriptions[service] DISABLE_REGISTRATIONtrue (défaut : false)
Lecture anonyme[service] REQUIRE_SIGNIN_VIEWtrue pour une forge interne
Installation[security] INSTALL_LOCKtrue après installation
URL publique[server] ROOT_URLhttps://git.exemple.fr/
Port webMappage Docker127.0.0.1:3000:3000
SSH GitMappage DockerPort dédié, ou supprimé si inutile
VersionTag de l'imageSérie majeure épinglée, jamais latest

Aller plus loin

Si vous avez besoin de l'intégration continue, isolez les exécuteurs de la forge sur une autre machine : un runner exécute du code arbitraire issu des dépôts. Pour surveiller l'instance, voir Uptime Kuma. Pour héberger plusieurs services sur le même serveur, Docker Compose sur un VPS Linux reste la base.

FAQ

Forgejo ou Gitea : lequel choisir ?

Forgejo est un fork de Gitea, géré par une organisation à but non lucratif, et les deux forges se ressemblent beaucoup à l'usage. Comparez leur gouvernance, leur rythme de publication et les fonctions dont vous avez besoin. Ce guide vaut pour les deux, avec quelques différences de noms (image, préfixe des variables d'environnement).

Quelle base de données utiliser ?

SQLite est la base par défaut de l'image Docker de Forgejo et suffit pour une petite équipe. Au-delà, ou si vous voulez des sauvegardes plus fines, préférez PostgreSQL ou MariaDB. Faites ce choix dès l'installation, car migrer ensuite demande du travail.

Comment empêcher n'importe qui de créer un compte ?

Passez DISABLE_REGISTRATION à true dans la section [service] de app.ini, ou via la variable FORGEJO__service__DISABLE_REGISTRATION=true avec Docker. Créez ensuite les comptes depuis l'interface d'administration. Vous pouvez aussi mettre REQUIRE_SIGNIN_VIEW à true pour masquer les dépôts aux visiteurs anonymes.

Faut-il exposer le port SSH de Git ?

Seulement si vous voulez cloner et pousser en SSH depuis l'extérieur. Utilisez alors un port distinct de celui d'administration du serveur, et limitez-le par pare-feu si vos utilisateurs ont des IP fixes. Sinon, le clonage en HTTPS avec jeton d'accès suffit.

Comment sauvegarder Forgejo ?

Sauvegardez le dossier de données monté dans le conteneur (dépôts, app.ini, SQLite éventuel) et exportez la base si vous utilisez PostgreSQL ou MariaDB. Arrêtez le service ou utilisez un dump cohérent avant de copier. Chiffrez la copie et stockez-la hors du VPS, et testez une restauration.

Comment mettre à jour Forgejo ?

Avec le tag de version majeure de l'image, un docker compose pull suivi d'un up -d applique les mises à jour mineures. Le passage d'une version majeure à la suivante exige une lecture des notes de version et une sauvegarde préalable. Ne suivez jamais le tag latest sans contrôle.