Zum Inhalt springen

~/CodeBlog.at

Private Composer-Pakete aus GitLab in CI/CD laden (Deploy Token & COMPOSER_AUTH)

·3 Min. Lesezeit

Veröffentlicht
Überarbeitet

Was ist neu: Lösung als Schritt-für-Schritt-Anleitung, Token-Scopes und die Alternative mit CI_JOB_TOKEN ergänzt.

Kurz & knapp

Damit Composer in einer GitLab-Pipeline private Pakete laden kann, braucht es Zugangsdaten. Am einfachsten: ein Deploy Token in der Gruppe der Pakete anlegen und als CI/CD-Variable COMPOSER_AUTH mit dem Inhalt {"gitlab-token": {"gitlab.example.com": {"username": "…", "token": "…"}}} hinterlegen. Alternativ funktioniert das automatische CI_JOB_TOKEN – das Projekt muss dann in der Allowlist der Paket-Projekte stehen.

Getestet mit: GitLab CE 14.10 (Lösung damals umgesetzt), Formate abgeglichen mit der aktuellen GitLab- und Composer-Doku

Inhalt
  1. Das Problem
  2. Die Lösung: Deploy Token + COMPOSER_AUTH
  3. Alternative: CI_JOB_TOKEN

Mein Deployment sah im April 2022 so aus: Mit jedem Commit ins GitLab startet ein GitLab-Runner einen Docker-Container mit dem Image t3easy/surf (öffnet in neuem Tab) (an dieser Stelle herzlichen Dank an Jan für das Docker-Image!), zieht sich das Projekt in den Container, baut die Frontend-Assets (via npm) und führt ein composer install aus. Danach spielt TYPO3 Surf das Projekt per rsync auf den Zielserver. Dazwischen und danach gibt es noch ein paar kleinere Schritte, aber im Großen und Ganzen ist das die ganze Magie.

Das Problem

Bis zu einem GitLab-Update (damals von 14.9 auf 14.10) lief das problemlos. Danach konnte Composer meine eigenen TYPO3-Extensions nicht mehr aus den privaten Paketen laden – bei jeder einzelnen Extension kam:

- Downloading websailor/extension (2.2.0)
  Failed to download websailor/extension from dist: Could not authenticate against gitlab.domain.com
  Now trying to download from source

Nach einigen Stunden Debugging konnte ich den Fehler zwar eingrenzen, aber nicht eindeutig zuordnen: Entweder hat sich in GitLab etwas geändert (in den Changelogs habe ich nichts Passendes gefunden) oder es lag an Composer. Alles andere war unverändert – auch das Docker-Image t3easy/surf:2-php7.4-composer2-node16.

Fest stand: Composer hatte im Container keine gültigen Zugangsdaten für meine GitLab-Instanz. Die Lösung: sie ihm explizit mitgeben.

Die Lösung: Deploy Token + COMPOSER_AUTH

Meine TYPO3-Extensions liegen alle in einer eigenen GitLab-Gruppe. Dafür lege ich einen Gruppen-Deploy-Token an und übergebe ihn Composer über die Umgebungsvariable COMPOSER_AUTH.

Befehle für dich anpassen

Deine Eingaben werden in allen Befehlen dieser Seite eingesetzt und nur in deinem Browser gespeichert.

  1. Deploy Token anlegen: In der Gruppe mit den Paketen unter Settings → Repository → Deploy tokens einen neuen Token erstellen – bei mir mit dem Username gitlab-runner. Als Scope genügt Lesezugriff:

    Pakete kommen aus … Scope
    Git-Repositories (vcs) read_repository
    der GitLab Package Registry read_package_registry
  2. CI/CD-Variable anlegen: Im Projekt, das deployt wird, unter Settings → CI/CD → Variables eine Variable COMPOSER_AUTH mit folgendem Inhalt erstellen – XXX ist der Token:

    {"gitlab-token": {"gitlab.example.com": {"username": "gitlab-runner", "token": "XXX"}}}

    Die Variable als Masked markieren, damit der Token nicht in Job-Logs auftaucht. Protected schränkt sie zusätzlich auf geschützte Branches ein – praktisch, wenn nur von main deployt wird.

  3. Pipeline neu starten – Composer liest COMPOSER_AUTH automatisch und kann die Pakete wieder laden.

Problem gelöst.

Alternative: CI_JOB_TOKEN

Jeder GitLab-CI-Job bekommt automatisch ein kurzlebiges Token, das CI_JOB_TOKEN. Laut GitLab-Doku lässt es sich direkt für Composer verwenden – ganz ohne eigenen Deploy Token:

composer config gitlab-token.gitlab.example.com gitlab-ci-token "${CI_JOB_TOKEN}"
composer install
Deploy Token + COMPOSER_AUTH CI_JOB_TOKEN
Einrichtung Token einmal pro Gruppe anlegen Allowlist pro Paket-Projekt pflegen
Gültigkeit bis zum Ablaufdatum bzw. Widerruf nur während des Jobs
Funktioniert auch lokal ja nein

Eine gute Erklärung, wie private Composer-Pakete mit GitLab grundsätzlich funktionieren, gibt es übrigens bei PHP.Watch (öffnet in neuem Tab).

Häufige Fragen

Was bedeutet „Could not authenticate against gitlab“ bei Composer?

Composer hat für die GitLab-Domain keine gültigen Zugangsdaten und kann das Paket deshalb nicht herunterladen. Im CI fehlen meist auth.json oder die Variable COMPOSER_AUTH.

Welchen Scope braucht der Deploy Token?

Für Pakete, die Composer direkt aus Git-Repositories lädt, read_repository. Nutzt du die GitLab Package Registry, read_package_registry.

Deploy Token oder CI_JOB_TOKEN?

Das CI_JOB_TOKEN gibt es automatisch in jedem Job und läuft danach ab – dafür muss das Projekt in der Allowlist der Paket-Projekte stehen. Ein Deploy Token ist einfacher einzurichten, muss aber sicher als Variable hinterlegt und bei Bedarf erneuert werden.

Wo lege ich die Variable COMPOSER_AUTH an?

Im Projekt oder in der Gruppe unter Settings → CI/CD → Variables, am besten als *Masked* und *Protected*.

Quellen & weiterführende Links

  1. Composer packages in the package registry – Authentifizierung (öffnet in neuem Tab) – GitLab Docs
  2. Deploy tokens (öffnet in neuem Tab) – GitLab Docs
  3. CI/CD job token (öffnet in neuem Tab) – GitLab Docs
  4. Authentication for privately hosted packages and repositories (öffnet in neuem Tab) – Composer Dokumentation
  5. Composer and GitLab: private repositories (öffnet in neuem Tab) – PHP.Watch
  6. t3easy/surf (Docker-Image) (öffnet in neuem Tab) – Docker Hub

Geschrieben von

Christoph Schwob (öffnet in neuem Tab)

Ich bin Christoph Schwob, halbkreativer Entwickler aus Österreich und arbeite seit über 10 Jahren an und mit TYPO3. Hier sammle ich Lösungen, Code-Snippets und Notizen rund um TYPO3, macOS, Server, Homelab und alles andere.

Suche

Tippe einen Suchbegriff ein.