📑 Sommaire ▾
- 01 Prérequis
- 02 Étape 1 : Installer Docker
- 03 Étape 2 : Pointer le DNS
- 04 Étape 3 : Préparer le réseau et les secrets
- 05 Étape 4 : Le docker-compose.yml de Gitea
- 06 Étape 5 : Reverse proxy HTTPS (Caddy)
- 07 Étape 6 : Installation initiale et compte administrateur
- 08 Étape 7 : Configurer le clonage SSH
- 09 Étape 8 : Activer Gitea Actions (CI/CD)
- 10 Étape 9 : Durcissement
- 11 Étape 10 : Sauvegarde
- 12 Dépannage
- 13 Vérification finale
- 14 FAQ
- · Gitea ou Forgejo, lequel choisir en 2026 ?
- · Pourquoi exposer le SSH sur le port 2222 plutôt que 22 ?
- · Gitea Actions est-il vraiment compatible avec GitHub Actions ?
- · Combien de ressources Gitea consomme-t-il ?
- · Puis-je migrer mes dépôts depuis GitHub ou GitLab ?
- · Faut-il utiliser PostgreSQL ou SQLite ?
- 21 Sur le même sujet
Héberger soi-même ses dépôts git, c’est échapper aux limites de tarification de GitHub, garder ses sources sur sa propre infrastructure et disposer d’une forge complète (issues, pull requests, wiki, CI/CD) qui tient sur un petit VPS. En 2026, Gitea reste la référence pour cela : écrite en Go, elle démarre en quelques secondes, consomme une fraction des ressources de GitLab et propose désormais Gitea Actions, un moteur CI/CD compatible avec la syntaxe des workflows GitHub.
Dans ce tutoriel, on déploie Gitea avec Docker et une base PostgreSQL, on l’expose proprement en HTTPS derrière un reverse proxy, on configure le SSH pour le clonage des dépôts, on active Gitea Actions, puis on durcit et sauvegarde l’ensemble.
Prérequis
- Un VPS sécurisé sous Ubuntu 24.04 LTS. Gitea est très léger : 1 vCPU et 2 Go de RAM suffisent pour un usage personnel ou en petite équipe. Un Hetzner CX22 fait largement l’affaire. Si le serveur n’est pas prêt, voyez installer et sécuriser un VPS Ubuntu.
- Docker et Docker Compose installés (commande à l’étape 1).
- Un nom de domaine dont vous contrôlez le DNS. On utilisera
git.exemple.fr. - Les ports 80 et 443 ouverts sur UFW, plus un port SSH dédié (on utilisera 2222) pour le clonage git, afin de ne pas entrer en conflit avec le SSH système du port 22.
- Un reverse proxy ; on montrera Caddy, mais Traefik ou Nginx Proxy Manager fonctionnent aussi.
Étape 1 : Installer Docker
Si Docker n’est pas présent :
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
docker --version && docker compose version
Étape 2 : Pointer le DNS
Créez un enregistrement A vers l’IP de votre VPS :
| Type | Nom | Valeur |
|---|---|---|
| A | git.exemple.fr | 203.0.113.10 |
Vérifiez la propagation :
dig +short git.exemple.fr
Étape 3 : Préparer le réseau et les secrets
Créez le réseau Docker partagé avec votre reverse proxy (si ce n’est pas déjà fait) :
docker network create web
Préparez le dossier et le mot de passe de la base :
mkdir -p ~/gitea && cd ~/gitea
echo "DB_PASS=$(openssl rand -base64 32 | tr -d '\n')" > .env
chmod 600 .env
Étape 4 : Le docker-compose.yml de Gitea
nano docker-compose.yml
services:
gitea:
image: docker.gitea.com/gitea:1.24
container_name: gitea
restart: unless-stopped
environment:
USER_UID: "1000"
USER_GID: "1000"
GITEA__database__DB_TYPE: postgres
GITEA__database__HOST: gitea-db:5432
GITEA__database__NAME: gitea
GITEA__database__USER: gitea
GITEA__database__PASSWD: ${DB_PASS}
# Domaine public servi par le reverse proxy
GITEA__server__DOMAIN: git.exemple.fr
GITEA__server__ROOT_URL: https://git.exemple.fr/
GITEA__server__SSH_DOMAIN: git.exemple.fr
GITEA__server__SSH_PORT: "2222"
# Désactive l'inscription publique après création de l'admin
GITEA__service__DISABLE_REGISTRATION: "true"
volumes:
- gitea_data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "2222:22" # SSH git (clonage)
networks:
- web
- internal
depends_on:
- gitea-db
gitea-db:
image: docker.io/library/postgres:16-alpine
container_name: gitea-db
restart: unless-stopped
environment:
POSTGRES_USER: gitea
POSTGRES_PASSWORD: ${DB_PASS}
POSTGRES_DB: gitea
volumes:
- gitea_db:/var/lib/postgresql/data
networks:
- internal
volumes:
gitea_data:
gitea_db:
networks:
web:
external: true
internal:
Points importants :
- On configure Gitea directement par variables d’environnement (
GITEA__section__clé), ce qui rend la config reproductible sans éditer leapp.inià la main. ROOT_URLest crucial : c’est l’URL publique en HTTPS. Une erreur ici casse les liens des clones et des webhooks.- Le SSH est exposé sur le port 2222 côté hôte, mappé sur le 22 du conteneur. Le SSH d’administration du serveur reste sur son port habituel.
- Le réseau
internalisole PostgreSQL ; seul Gitea rejointwebpour être joignable par le proxy.
Lancez :
docker compose up -d
Étape 5 : Reverse proxy HTTPS (Caddy)
Ajoutez ce bloc à votre Caddyfile :
git.exemple.fr {
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
reverse_proxy gitea:3000
}
Gitea sert son interface web sur le port 3000 en interne ; Caddy résout gitea:3000 via le réseau web et gère le certificat Let’s Encrypt automatiquement. Rechargez :
docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile
Pour un déploiement Caddy complet à partir de zéro, suivez reverse proxy HTTPS automatique avec Caddy et Docker.
Piège fréquent : ne mappez pas le port 3000 dans la section
ports:du compose. Le HTTP de Gitea ne doit jamais être exposé directement sur Internet ; tout passe par Caddy. Seul le port SSH (2222) est publié, car le protocole git over SSH ne transite pas par le proxy HTTP.
Étape 6 : Installation initiale et compte administrateur
Rendez-vous sur https://git.exemple.fr. L’assistant d’installation s’affiche, pré-rempli grâce aux variables d’environnement. Vérifiez que le type de base est bien postgres et que l’URL racine est correcte, puis descendez à la section Compte administrateur : créez votre utilisateur admin (nom, e-mail, mot de passe robuste). Validez.
Comme on a positionné DISABLE_REGISTRATION: "true", plus personne ne peut s’inscrire librement : vous ajouterez les comptes manuellement depuis le panneau d’administration. Pour une instance familiale ou d’équipe restreinte, c’est le réglage recommandé.
Étape 7 : Configurer le clonage SSH
Ouvrez le port SSH dédié dans le pare-feu :
sudo ufw allow 2222/tcp
Dans Gitea, ajoutez votre clé publique SSH via Paramètres → Clés SSH/GPG. Vous clonerez alors un dépôt ainsi :
git clone ssh://git@git.exemple.fr:2222/votre-user/votre-repo.git
Pour éviter de retaper le port à chaque fois, ajoutez un bloc à ~/.ssh/config sur votre poste :
Host git.exemple.fr
Port 2222
User git
Étape 8 : Activer Gitea Actions (CI/CD)
Gitea Actions est activé par défaut dans les versions récentes. Pour exécuter des workflows, il faut enregistrer au moins un runner (act_runner). Récupérez d’abord un jeton dans Administration → Actions → Runners → Créer le jeton d'enregistrement, puis déployez le runner :
services:
runner:
image: docker.gitea.com/act_runner:latest
container_name: gitea-runner
restart: unless-stopped
environment:
GITEA_INSTANCE_URL: https://git.exemple.fr
GITEA_RUNNER_REGISTRATION_TOKEN: "VOTRE_JETON"
GITEA_RUNNER_NAME: runner-principal
volumes:
- runner_data:/data
- /var/run/docker.sock:/var/run/docker.sock
volumes:
runner_data:
Lancez-le (docker compose up -d). Le runner apparaît alors comme « Idle » dans l’interface. Vous pouvez désormais ajouter des workflows dans .gitea/workflows/ de vos dépôts, avec une syntaxe quasi identique à GitHub Actions.
Note de sécurité : monter
/var/run/docker.sockdonne au runner un accès complet au démon Docker de l’hôte. Pour une instance exposée à des contributeurs non fiables, isolez le runner sur une VM ou un hôte séparé.
Étape 9 : Durcissement
- Forcez le HTTPS partout (déjà géré par Caddy avec HSTS). Vérifiez votre note sur SSL Labs.
- Désactivez l’inscription ouverte (
DISABLE_REGISTRATION: "true", déjà fait) et activez le MFA sur votre compte admin dans les paramètres de sécurité. - Limitez les e-mails sortants si vous n’avez pas de SMTP : désactivez les notifications par mail plutôt que d’exposer un relais ouvert.
- Restreignez la création d’organisations aux administrateurs via
GITEA__service__DEFAULT_ALLOW_CREATE_ORGANIZATION: "false". - Maintenez l’image à jour. Surveillez les versions mineures de Gitea (correctifs de sécurité fréquents) et mettez à jour le tag après avoir sauvegardé.
Étape 10 : Sauvegarde
Gitea fournit une commande de dump qui archive la base, les dépôts et la configuration en un seul fichier :
docker compose exec -u git gitea gitea dump -c /data/gitea/conf/app.ini -f /data/gitea-dump.zip
Récupérez l’archive depuis le volume, puis copiez-la hors site. Couplée à un stockage objet, c’est une stratégie de reprise solide ; notre tutoriel sauvegarde automatique chiffrée avec restic et Backblaze montre comment automatiser l’envoi offsite de ce dump. Pensez aussi à sauvegarder séparément le volume gitea_db pour une restauration PostgreSQL fine.
Dépannage
- Les liens de clone affichent
localhostou un mauvais port.ROOT_URL,SSH_DOMAINouSSH_PORTsont mal renseignés. Corrigez les variables et relancez le conteneur. Permission denied (publickey)au clone SSH. Soit le port n’est pas 2222 dans votre commande, soit la clé n’est pas ajoutée à votre compte Gitea, soit UFW bloque le port 2222.- Erreur 502 via le proxy. Caddy ne joint pas
gitea:3000: vérifiez le réseauwebpartagé et que le conteneur tourne (docker logs gitea). - Gitea ne se connecte pas à la base. Le mot de passe
DB_PASSdiffère entre les deux services, ou PostgreSQL n’a pas fini de démarrer. Consultezdocker logs gitea-db. - Les Actions restent « Waiting ». Aucun runner n’est enregistré ou son jeton a expiré. Régénérez un jeton et relancez le runner.
Vérification finale
# Les conteneurs tournent
docker compose ps
# L'interface répond en HTTPS
curl -sI https://git.exemple.fr | head -1
# Le port SSH git est ouvert
nc -zv git.exemple.fr 2222
Créez un premier dépôt, clonez-le en SSH, poussez un commit : votre forge git est opérationnelle.
FAQ
Gitea ou Forgejo, lequel choisir en 2026 ?
Forgejo est un fork communautaire de Gitea né d’un désaccord sur la gouvernance ; les deux restent très proches techniquement. Gitea bénéficie d’un développement soutenu et de Gitea Actions matures ; Forgejo met l’accent sur la gouvernance non lucrative et le fédéré. Pour un choix détaillé, voyez Gitea vs Forgejo vs GitLab.
Pourquoi exposer le SSH sur le port 2222 plutôt que 22 ?
Parce que le port 22 de l’hôte est déjà utilisé par le SSH d’administration du serveur. Exposer le SSH git du conteneur sur un port distinct (2222) évite tout conflit et garde une séparation claire entre l’accès système et l’accès aux dépôts.
Gitea Actions est-il vraiment compatible avec GitHub Actions ?
La syntaxe des workflows est largement compatible : la plupart des fichiers .yml simples fonctionnent tels quels. Les différences apparaissent sur les actions du Marketplace GitHub spécifiques et certaines fonctionnalités avancées. Pour des pipelines standards (build, test, déploiement), la migration est généralement immédiate.
Combien de ressources Gitea consomme-t-il ?
Très peu : l’instance Gitea elle-même tourne sous 200 Mo de RAM au repos, et PostgreSQL en ajoute environ 100 à 200 Mo. C’est l’un des principaux arguments face à GitLab, qui exige plusieurs Go de RAM. Un VPS d’entrée de gamme suffit pour une petite équipe.
Puis-je migrer mes dépôts depuis GitHub ou GitLab ?
Oui. Gitea propose une fonction de migration intégrée (Nouveau → Migration) qui importe non seulement le code, mais aussi les issues, les pull requests, les labels et les jalons depuis GitHub, GitLab et d’autres forges. Fournissez l’URL du dépôt source et un jeton d’accès si nécessaire.
Faut-il utiliser PostgreSQL ou SQLite ?
SQLite suffit pour un usage strictement personnel à faible trafic et simplifie le déploiement. Dès que vous prévoyez plusieurs utilisateurs actifs, des Actions ou une croissance future, PostgreSQL (comme dans ce tutoriel) offre de meilleures performances concurrentes et une sauvegarde plus robuste.
Sur le même sujet
- Gitea vs Forgejo vs GitLab : quelle forge git self-hosted en 2026
- Reverse proxy HTTPS automatique avec Caddy et Docker
- Sauvegarde automatique chiffrée avec restic et Backblaze
- Installer et sécuriser un VPS Ubuntu de A à Z
Avec Gitea déployé en Docker derrière un reverse proxy HTTPS, vous disposez d’une forge git complète, rapide et frugale, capable de faire tourner vos pipelines CI/CD sans la lourdeur de GitLab. C’est l’outil idéal pour reprendre la main sur vos sources. Pour suivre les nouvelles versions et les failles à corriger sur vos outils self-hosted, abonnez-vous à notre bot de veille Telegram.