Tutoriel

Migrer GitLab.com vers une instance self-managed sur VPS

Déploiement11 min de lecture14 étapes

Votre agence garde le code de plusieurs clients sur un compte GitLab.com, et la facture comme la rétention ne sont pas réglées par vous. Reprendre la main passe par une instance GitLab sur votre propre VPS, mais l'export de projet n'emporte pas tout : variables CI/CD, images du registre, webhooks et jetons restent derrière. Ce guide planifie la migration, déroule le direct transfer, règle le rattachement des membres et reconstitue ce qui manque, avec un ordre de bascule réversible. L'ancien projet reste en lecture seule jusqu'à validation.

Sommaire· Pourquoi sortir de GitLab.com pour une instance self-managed1/14
  1. 01Pourquoi sortir de GitLab.com pour une instance self-managed
  2. 02Ce que vous gagnez en reprenant l'hébergement
  3. 03Ce que la migration n'emporte pas, à inventorier avant tout
  4. 04Export de projet ou direct transfer : ce que chaque méthode couvre
  5. 05Prérequis : versions, droits et ressources de votre instance
  6. 06Planifier et exécuter la migration, de l'inventaire à la bascule
  7. 07Membres et assignees : la règle de rattachement
  8. 08Variables CI/CD et registre de conteneurs : reconstituer à la main
  9. 09Transférer les images du registre vers la nouvelle URL
  10. 10Gardez la marche arrière ouverte
  11. 11Dépannage : les erreurs d'authentification et d'import
  12. 12Contrôles avant de couper l'ancien accès
  13. 13La documentation officielle
  14. 14Et ensuite : consolider autour de votre instance

Pourquoi sortir de GitLab.com pour une instance self-managed

Quand les tarifs d'un outil SaaS bougent, comme la récente hausse d'Atlassian Cloud détaillée dans notre article sur le double choc tarifaire, les équipes réévaluent tout leur outillage de développement. Pour une agence, la question est concrète : le code de dix clients vit sur un compte unique, chez un tiers, avec une rétention et des accès que l'on ne règle pas soi-même.

Une instance auto-gérée déplace ces décisions chez vous : où sont stockés les dépôts, combien de temps on garde les artefacts, qui peut se connecter, et ce que cela coûte chaque mois. Le prix de cette liberté est un travail de migration que GitLab ne fait pas entièrement à votre place.

Ce guide ne reprend ni le choix de la forge, traité dans le comparatif des forges, ni l'installation, décrite dans le guide d'installation de GitLab CE. Il part d'une instance GitLab déjà en ligne et s'occupe uniquement du passage de GitLab.com vers elle.

Ce que vous gagnez en reprenant l'hébergement

  • Des accès sous votre contrôle — comptes, groupes et rôles se gèrent sur votre instance, pas sur un compte SaaS partagé entre clients.
  • Une rétention que vous fixez — durée de conservation des artefacts et des journaux, volume du registre, tout se règle dans l'administration.
  • Une facture qui suit votre VPS — le coût dépend de la machine que vous dimensionnez, pas d'un nombre de sièges.
  • Un nom de domaine à vous — le dépôt répond sur git.votre-domaine.com, avec votre certificat et votre pare-feu.
  • Une migration par étapes — l'ancien projet reste en place, en lecture seule, tant que le nouveau n'est pas validé.

Ce que la migration n'emporte pas, à inventorier avant tout

La documentation officielle de l'export de projet liste ce qui n'est pas exporté : l'historique des pipelines enfants, les déclencheurs de pipeline, les traces et artefacts de jobs CI/CD, les images du registre de conteneurs et de paquets, les variables CI/CD, les webhooks, les jetons chiffrés, le nombre d'approbations requises, les clés de déploiement autorisées sur les branches protégées, les fichiers sécurisés et les variables des planifications de pipeline. Les clés de déploiement ne sont pas non plus importées : il faut les réactiver dans le projet importé.

Le direct transfer a sa propre liste d'exclusions, qui recoupe la première : variables CI/CD, webhooks, images du registre, registre de paquets, journaux et artefacts de jobs. Au niveau du groupe, les variables CI/CD, les jetons de déploiement et les règles de push ne suivent pas non plus.

Écrivez cet inventaire dans un tableau avant de commencer : une ligne par projet, une colonne par élément manquant, une colonne pour la personne qui le recrée. C'est ce document, plus que l'export lui-même, qui vous protège le jour où l'ancien accès ferme.

Export de projet ou direct transfer : ce que chaque méthode couvre

Faites défiler le tableau

ÉlémentExport de projet (fichier)Direct transfer
GranularitéUn projet à la fois, via un fichier téléchargéGroupes entiers, avec ou sans leurs projets, depuis l'interface
Variables CI/CDNon exportéesNon migrées
Images du registre de conteneursNon exportéesNon migrées
WebhooksNon exportésNon migrés
Journaux et artefacts de jobsNon exportésNon migrés
MembresRattachés si l'e-mail public source correspond à l'e-mail principal de destinationRattachés si l'e-mail public source correspond à un e-mail confirmé de destination
Ce qu'il faut côté instanceUn administrateur réalise l'importFonction activée par un administrateur, jeton avec le scope `api` côté source

Prérequis : versions, droits et ressources de votre instance

Première règle, la version. L'import d'un fichier accepte des exports issus d'une version jusqu'à deux versions mineures en arrière de la destination, et la documentation demande que la destination soit au moins à la version de la source. Pour le direct transfer, la documentation recommande GitLab 16.8 ou plus récent des deux côtés, et demande qu'une source ne retarde pas de plus de deux versions mineures sur la destination. GitLab.com avance en continu : visez la dernière version stable disponible pour votre instance, mettez-la à jour avant de migrer, pas après, et relisez l'écart toléré dans la documentation le jour J.

Côté droits, il vous faut le rôle Owner sur le groupe source, un administrateur sur l'instance cible, et un jeton d'accès personnel avec le scope api créé sur GitLab.com. Les deux instances doivent se joindre en HTTPS, avec de l'espace libre dans /tmp.

Côté ressources, notre recommandation éditoriale : 4 vCPU et 8 Go de RAM pour une instance qui héberge aussi le registre, un disque NVMe dimensionné sur la taille cumulée des dépôts et des images, et des runners sur un VPS à part dès que les builds sont lourds. L'installation elle-même est décrite dans le guide GitLab CE sur VPS.

Planifier et exécuter la migration, de l'inventaire à la bascule

  1. Inventorier groupes, projets et dépendances

    Listez chaque groupe, chaque projet, ses variables, ses webhooks, ses runners et ses intégrations. Notez qui en est propriétaire côté client.

  2. Mettre l'instance cible à jour

    Vérifiez la version dans l'administration, et visez la dernière version stable disponible, au moins égale à celle de GitLab.com, avant tout import.

  3. Créer les utilisateurs sur la cible

    Les membres ne se créent pas pendant la migration. Créez les comptes avant, avec l'e-mail principal que chaque personne utilise sur GitLab.com.

  4. Prévoir un groupe par client

    Créez sur la cible un groupe ou sous-groupe par client, avec les droits minimaux, avant d'importer.

  5. Faire publier les e-mails côté source

    Chaque membre renseigne un e-mail public dans son profil GitLab.com, au moins jusqu'à la fin de l'import.

  6. Activer le direct transfer sur l'instance cible

    Un administrateur active la migration de groupes par direct transfer dans les paramètres de l'application. Elle est désactivée par défaut sur une instance auto-gérée.

  7. Lancer l'import du groupe

    Sur la cible, choisissez Create new puis New group puis Import group, saisissez https://gitlab.com et votre jeton, puis Connect instance. Sélectionnez les groupes avec Import with projects.

  8. Exporter à la main les projets isolés

    Pour un projet hors groupe, ouvrez Settings puis General puis Advanced puis Export project, téléchargez le fichier et importez-le sur la cible.

  9. Suivre l'import et relire les erreurs

    La colonne Status indique l'avancement. Sur un import en échec ou partiel, Show errors détaille la cause. Comptez plusieurs heures pour un grand nombre de projets.

  10. Brancher la suite sur le registre et la CI

    Reconstituez variables et images comme décrit plus bas, puis relancez un pipeline complet sur la cible avant de toucher à l'ancien projet.

Membres et assignees : la règle de rattachement

Sur une instance auto-gérée, la règle publiée est la suivante : les utilisateurs doivent déjà exister sur la destination, et l'e-mail public du compte source doit correspondre à l'e-mail principal du compte de destination. Si les conditions sont réunies, la personne est ajoutée comme membre direct. Sinon, l'association passe à l'utilisateur qui réalise l'import : vos auteurs de commentaires et vos assignees se retrouvent tous à votre nom.

Avant l'import, vérifiez sur chaque profil GitLab.com le champ Public email. Pour un export de projet, vous pouvez aussi ajouter des e-mails publics en éditant le fichier project_members.ndjson de l'archive. Le propriétaire du groupe de premier niveau doit lancer l'export pour que les membres directs et hérités soient inclus, et un administrateur doit réaliser l'import.

Avec le direct transfer, les adhésions importées sont d'abord associées à des utilisateurs substituts, avant réaffectation. Une case Import user memberships permet aussi de ne pas importer les adhésions. Dans ce cas, c'est l'e-mail public source face à un e-mail confirmé de destination qui décide du rattachement, pas l'e-mail principal comme pour l'import de fichier.

Pour une agence, structurez la cible avant d'importer : un groupe de premier niveau par client, ou un sous-groupe par client sous un groupe d'agence. Donnez à chaque client le rôle minimal sur son seul groupe (Reporter ou Developer plutôt qu'Owner), gardez le rôle Owner pour l'équipe interne, et vous pourrez plus tard sortir un client en lui transférant son groupe ou en exportant ses projets, sans toucher aux autres.

Variables CI/CD et registre de conteneurs : reconstituer à la main

Les variables ne voyagent pas, parce que GitLab les considère comme sensibles. Listez-les côté source avec l'API : curl --header "PRIVATE-TOKEN: <jeton>" "https://gitlab.com/api/v4/projects/<id>/variables". La liste donne clé, attributs masked et protected et, en général, la valeur ; mais toutes les valeurs ne sont pas forcément relisibles, selon la version et la façon dont la variable a été créée.

Recréez-les ensuite sur la cible avec curl --request POST --header "PRIVATE-TOKEN: <jeton>" --form "key=NOM" --form "value=valeur" "https://git.votre-domaine.com/api/v4/projects/<id>/variables". La clé accepte 255 caractères parmi A-Z, a-z, 0-9 et _. Quand la valeur manque ou reste masquée, recréez le secret chez son fournisseur et notez-le dans le coffre de l'agence.

Les variables de groupe se recréent depuis les réglages CI/CD du groupe. Les runners, eux, se réenregistrent sur la nouvelle instance : leurs jetons ne suivent pas.

Transférer les images du registre vers la nouvelle URL

  1. Activer le registre sur l'instance cible

    Dans /etc/gitlab/gitlab.rb, définissez registry_external_url en HTTPS, par exemple https://registry.votre-domaine.com, puis lancez sudo gitlab-ctl reconfigure. Le registre exige un certificat TLS.

  2. Créer un jeton pour chaque côté

    Un jeton avec read_registry suffit pour tirer les images, et write_registry en plus pour les pousser.

  3. Tirer chaque image depuis l'ancienne URL

    Connectez-vous avec docker login registry.gitlab.com, puis docker pull registry.gitlab.com/groupe/projet/image:tag.

  4. Retaguer puis pousser vers la cible

    Exécutez docker tag registry.gitlab.com/groupe/projet/image:tag registry.votre-domaine.com/groupe/projet/image:tag, puis docker login registry.votre-domaine.com et docker push registry.votre-domaine.com/groupe/projet/image:tag. Les chemins de dépôt du registre s'écrivent en minuscules.

Gardez la marche arrière ouverte

Ne supprimez rien à la source. Passez l'ancien projet en archivé ou retirez les droits d'écriture, gardez-le lisible, puis relancez un pipeline et un git clone complet depuis la cible. Tant que la validation n'est pas signée par le client, la bascule reste réversible : il suffit de réouvrir l'ancien projet.

Dépannage : les erreurs d'authentification et d'import

Au docker login ou au docker push, le message access forbidden signifie, selon la documentation, que l'en-tête Authorization a été retiré avant d'atteindre GitLab, souvent par un proxy placé devant l'instance. Vérifiez la configuration du reverse proxy.

Une erreur UNAUTHORIZED (401) indique des identifiants faux ou expirés, des scopes manquants, ou un mot de passe utilisé avec la double authentification activée : utilisez alors un jeton. Un DENIED (403) veut dire que les identifiants sont valides mais sans droit sur le registre.

Sur une grosse image, unauthorized: authentication required signale un jeton expiré avant la fin du push. Un administrateur peut allonger sa durée.

Côté import, un titre de jalon déjà existant reçoit un suffixe unique du type 18.0 (imported-…) : renommez le jalon avant la migration pour l'éviter.

Contrôles avant de couper l'ancien accès

  • Dépôts identiques — comparez les branches et les tags, puis faites un clone complet depuis la cible.
  • Pipeline complet vert — un pipeline sur la branche principale avec les variables recréées et les runners réenregistrés.
  • Images présentes — chaque tag utilisé par un déploiement existe dans le nouveau registre.
  • Membres et rôles relus — aucun auteur ni assignee n'a basculé sur le compte qui a lancé l'import.
  • Webhooks et clés de déploiement recréés — intégrations de chat, de déploiement et de supervision comprises.
  • Validation écrite par le client — l'ancien projet ne se ferme qu'après cet accord.

La documentation officielle

Les règles de ce guide viennent de la documentation GitLab : export et import de projet, migration de groupes par direct transfer, éléments migrés, API des variables de projet, authentification au registre et registre sur une instance auto-gérée. Relisez-les à la date de votre migration : les listes d'éléments migrés évoluent.

Et ensuite : consolider autour de votre instance

Une fois les projets validés, l'instance devient le point central du portefeuille de l'agence. Pour un registre plus lourd, Harbor sur un VPS peut prendre le relais. Si votre migration vient d'un autre outil de tickets, le guide Jira vers OpenProject ou Plane suit la même logique d'inventaire. Et si vous hésitez encore sur la forge, le passage de GitLab vers Gitea reste une option plus légère.

Reprenez la main sur le code de vos clients

Une agence qui héberge ses dépôts sur sa propre instance maîtrise ses accès, sa rétention et sa facture. Sur ServOrbit, l'instance tourne sur un VPS root à IPv4 dédiée, et le nom de domaine du dépôt se gère au même endroit que vos hébergements et votre revendeur.

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.

Écrire sur WhatsApps'ouvre dans un nouvel onglet