GitLab self-hosted en 2026 : retour d'expérience après 6 mois de prod sur 5 utilisateurs
Setup, ressources, OAuth Discord, Container Registry, CI runners. Honest review d'un GitLab CE en prod, avec les pièges concrets et les choix qui marchent.
TL;DR : GitLab CE 18.x self-hosted en 2026 reste un excellent choix pour 5-50 utilisateurs si tu acceptes ~4-8 GB RAM en runtime et 30 min de setup initial. La grosse upgrade vs 2024 : OAuth générique enfin propre, Container Registry stable, et MCP server officiel (135 outils). Pièges concrets ci-dessous.
Le contexte
J’utilise GitLab CE 18.x en self-hosted depuis 6 mois sur une VM Ubuntu 24.04 (192.168.10.93, 4 vCPU, 12 GB RAM, 200 GB SSD). 5 utilisateurs effectifs, ~40 projets, ~30 GB de repos cumulés, runners CI séparés sur une autre VM. Cet article résume ce qui marche, ce qui m’a planté, et ce que je referais différemment.
Pourquoi self-hosted (vs gitlab.com)
Mes raisons concrètes en 2026 :
- Pas de quota minute CI : sur gitlab.com gratuit, c’est 400 min/mois. Mes pipelines Astro + Docker pèsent ~10 min chacune × 10/jour = vite saturé. Self-hosted = illimité.
- Privacy : code propriétaire qui ne traîne nulle part chez un tiers.
- Container Registry inclus : depuis GitLab 17.x, l’auth registry self-hosted est stable. Plus besoin de Harbor à côté.
- MCP officiel : depuis fin 2025, GitLab fournit un MCP server officiel qui expose 135 outils aux LLMs (créer issue, MR, lire fichier, etc.). Énorme productivity boost si tu codes avec Claude/GPT/Cursor.
Setup initial — 30 min réelles
Pré-requis hardware
- Minimum réel 2026 : 4 vCPU / 8 GB RAM (4 GB ça swap dès qu’un GC tourne)
- Recommandé : 4 vCPU / 12 GB RAM
- Disque : SSD obligatoire. HDD = pipelines 5× plus lents.
J’ai testé sur Hostinger VPS Cloud (KVM 4 vCPU / 8 GB / 200 GB NVMe, ~7€/mois — voir offres VPS [lien affilié]). Ça marche. Mais le mieux reste un homelab si tu peux te le permettre.
Install Omnibus
# Ubuntu 24.04
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
sudo EXTERNAL_URL="https://git.exemple.com" apt install gitlab-ce
30 sec d’install paquets, 5 min de reconfigure auto au premier gitlab-ctl reconfigure. C’est tout.
Piège #1 : si tu mets EXTERNAL_URL=http://... et que tu veux passer en HTTPS plus tard avec un reverse proxy externe (Caddy / Traefik), il faut explicitement désactiver le Let’s Encrypt embedded dans /etc/gitlab/gitlab.rb :
letsencrypt['enable'] = false
nginx['listen_https'] = false
nginx['listen_port'] = 80
external_url 'https://git.exemple.com' # quand même HTTPS dans l'URL
Sinon le bundled nginx essaie d’émettre un cert tout seul → conflit avec ton Caddy externe.
OAuth Discord — enfin fonctionnel en 2026
Depuis GitLab 17.5, l’OAuth via oauth2_generic marche pour Discord sans contournement. Dans /etc/gitlab/gitlab.rb :
gitlab_rails['omniauth_providers'] = [
{
name: 'oauth2_generic',
label: 'Discord',
app_id: 'DISCORD_APP_ID',
app_secret: 'DISCORD_APP_SECRET',
args: {
client_options: {
site: 'https://discord.com',
authorize_url: '/api/oauth2/authorize',
token_url: '/api/oauth2/token',
user_info_url: '/api/users/@me'
},
user_response_structure: {
root_path: [],
id_path: ['id'],
attributes: {
nickname: 'username',
first_name: 'global_name',
email: 'email',
image: 'avatar'
}
},
authorize_params: {
scope: 'identify email'
},
strategy_class: "OmniAuth::Strategies::OAuth2Generic"
}
}
]
Piège #2 : Discord ne renvoie pas un avatar URL directement utilisable, juste un hash. GitLab affiche du Gravatar identicon par défaut. Solution : cron quotidien qui sync les avatars Discord vers GitLab via leur API admin. Script de ~50 lignes Python.
Container Registry — l’amélioration 2026
Setup auth registry self-hosted enfin propre depuis GitLab 17.x :
# /etc/gitlab/gitlab.rb
registry_external_url 'https://registry.git.exemple.com'
registry_nginx['listen_https'] = false
registry_nginx['listen_port'] = 5050
- vhost Caddy/Traefik externe qui forward 5050 → 5050 avec TLS termination.
Une fois en place, push direct depuis pipeline CI :
# .gitlab-ci.yml
docker:build:
stage: build
image: docker:24-cli
services:
- docker:24-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
Auth automatique via les variables CI. Plus besoin de Harbor / DockerHub.
CI Runners — séparation des préoccupations
Piège #3 : ne pas mettre les runners sur le même host que le serveur GitLab. C’est la garantie d’un GitLab qui swappe pendant les pipelines lourdes.
J’ai mis 2 GitLab Runners (concurrent=3 chacun) sur un host séparé (mini-PC Intel N100 avec 8 GB RAM, ~150€). Auto-register par token, Docker executor avec image custom Node 20 + Astro pré-installé pour gagner du cache.
Mesure : pipeline Astro + Docker build = 2-4 min sur runners séparés vs 8-12 min si runners sur GitLab host (le serveur lui-même qui se concurrence).
Backups — la partie qu’on oublie
# Cron quotidien
sudo gitlab-backup create STRATEGY=copy
# → /var/opt/gitlab/backups/TIMESTAMP_NN.X_gitlab_backup.tar
Piège #4 : la backup ne contient PAS /etc/gitlab/gitlab.rb ni /etc/gitlab/gitlab-secrets.json. Si tu restaures sans, ton instance ne décrypte pas ses propres secrets. Backup ces 2 fichiers séparément (chiffrés).
J’envoie tout vers un MinIO self-hosted sur une autre VM via rclone, rotation 30 jours. Coût additionnel : 0€ (homelab).
Le verdict après 6 mois
Ce qui marche super
- Stabilité : 99,9% d’uptime sur 6 mois (1 incident : OOM kill quand j’ai poussé un repo de 4 GB sans Git LFS)
- Performances : pipelines 2-4 min sur stack Node/Docker
- OAuth Discord : zéro friction pour ajouter des potes / collaborateurs
- Container Registry : 30 images en prod, aucun souci
Ce qui m’a planté
- Upgrade 17 → 18 : 25 min de downtime (vs estimés 5 min) à cause d’une migration de schéma DB. Lire les release notes AVANT de planifier l’upgrade.
- GitLab Pages : nécessite une wildcard DNS + cert wildcard. Pas évident à setup avec Caddy externe. J’ai contourné en utilisant Cloudflare Pages externes pour le statique.
- Mémoire : GitLab “respire” entre 4 et 8 GB selon le worker Sidekiq actif. Sans 12 GB de marge, ça finit en OOM kill.
Alternative à considérer
Si tu es 1-3 personnes et que tu fais peu de CI : Gitea + Drone ou Forgejo pèsent ~200 MB RAM en runtime (vs 4-8 GB pour GitLab). Pour du code-only sans pipeline lourde, c’est beaucoup plus light.
Mais dès que tu veux Container Registry + OAuth + CI matures + UI complète + MCP server : GitLab CE reste meilleur.
Outils complémentaires que j’utilise
- Bitdefender GravityZone sur le host GitLab : un EDR sérieux est non-négociable quand tu exposes un service Git en public (offres GravityZone — lien affilié)
- Hostinger VPS Cloud : si tu n’as pas de homelab, c’est le rapport qualité/prix le plus solide en 2026 (voir VPS — lien affilié)
- NordVPN : pour admin SSH depuis l’extérieur sans exposer port 22 (NordVPN — lien affilié)
FAQ
Combien ça coûte vraiment self-hosted ? Si tu as déjà un homelab : 0 € / mois (électricité ~5 €/mois sur un mini-PC). Sur VPS : 7-15 € / mois pour 4 vCPU / 12 GB.
GitLab EE vs CE en 2026 ? CE couvre 95% des use cases pour <50 users. EE devient pertinent au-dessus, pour les features de gestion de portfolio (epics croisés, value stream analytics, etc.).
GitLab.com gratuit suffit pour démarrer ? Oui, jusqu’à ce que tu sois bloqué par les 400 min CI/mois. Migrer hors gitlab.com est ensuite trivial (export project complet via API).
Vaut mieux GitHub ? GitHub Enterprise self-hosted = nettement plus cher (~21 $/user/mois) pour un set de features comparable. GitLab CE = $0.
Disclosure affiliation
Cet article contient des liens affiliés. Voir disclosure complète. Ces liens ne modifient pas le contenu ou les recommandations — j’utilise GitLab CE depuis 6 mois en self-hosted et c’est mon retour brut.
Article rédigé le 28 mai 2026.
Article rédigé par Adrien Marchand. Tags : gitlabself-hostedci-cddevopsoauthcontainer-registry