Node.js-Docker-Images in GitHub Packages mit GitHub Actions verwalten
13. Juli 2021
0 Min. LesezeitWenn Sie heute Open-Source-Entwicklung betreiben, sind Sie wahrscheinlich in der GitHub-Community aktiv – und beteiligen sich an Open-Source-Projekten und ihren Repositorys. Eine neuere Ergänzung des GitHub-Ökosystems ist GitHub Packages. Der Dienst wurde 2019 angekündigt und erhält nun mit der allgemeinen Verfügbarkeit der Container-Registry von GitHub Packages weitere Updates. Damit können wir Docker-basierte Images und alle anderen OCI-kompatiblen Formate vollständig innerhalb des GitHub-Ökosystems veröffentlichen und abrufen.
In diesem Beitrag führe ich Sie Schritt für Schritt durch einen GitHub-Actions-Workflow. Sie erfahren, wie Sie Node.js-Projekte als Docker-Images veröffentlichen und anschließend in die Container-Registry von GitHub Packages übertragen.
Bevor wir beginnen: Wussten Sie, dass es ein eigenes Supportforum für GitHub-Nutzer gibt, die GitHub Support Community? Schauen Sie vorbei, wenn Sie Hilfe benötigen.
Für diesen Beitrag verwenden wir das Node.js-Projekt dockly, ein Open-Source-Kommandozeilentool für Node.js, das eine immersive Terminaloberfläche zur Verwaltung von Docker-Containern und -Diensten bietet.

Einen GitHub-Actions-Workflow erstellen
Rufen Sie Ihr Open-Source-Repository auf GitHub auf und klicken Sie auf den Tab Actions, dann auf New Workflow und anschließend auf set up a workflow yourself. Die Ansicht sollte dann so aussehen:

Zuerst legen wir den Dateinamen des Workflows fest: docker-publish.yml oder eine andere Namenskonvention Ihrer Wahl.
GitHub füllt den Workflow-Code möglicherweise automatisch aus. Löschen Sie in diesem Fall einfach den gesamten Inhalt und fügen Sie Folgendes ein:
Der obige Workflow legt die folgenden Konventionen fest:
Der Workflow wird nur bei Commits im main-Branch oder bei Pull Requests an den main-Branch ausgeführt. Hinweis: Wenn Ihr Repository noch die frühere Konvention mit dem master-Branch verwendet, sollten Sie den Namen hier und im restlichen Codebeispiel entsprechend ändern. Der Workflow wird außerdem bei jedem Push von Tags im Semver-Format
<v*.*.*>an das Repository ausgeführt. Das ist praktisch, weil wir so für jede Version Docker-Images veröffentlichen können.Dadurch wird sichergestellt, dass beim Veröffentlichen eines neuen Docker-Images auch GitHub-Repository-Tags erstellt werden.
Für die übrigen Workflow-Jobs werden globale Umgebungsvariablen eingerichtet, die auf die GitHub Container Registry (ghcr.io) verweisen. Außerdem wird der Name des Docker-Images nach der üblichen Konvention von Docker Hub festgelegt:
<user>/<repo>, zum Beispiellirantal/nodejs-app.
Als Nächstes definieren wir unsere Jobs und richten einen Prozess zum Erstellen und anschließenden Veröffentlichen des Docker-Images ein.
Docker-Image als Teil des GitHub-Actions-Workflows erstellen
Um Docker-Images in der Container-Registry von GitHub Packages (oder auch nur auf GitHub) veröffentlichen zu können, müssen wir uns zuerst mit einem gültigen Konto authentifizieren. Deshalb besteht der erste Schritt im Build- und Publish-Job darin, sich anzumelden.
Fügen Sie den folgenden Code direkt unter dem zuvor eingefügten Code ein:
Sehen wir uns die Aktionen an, die von den hier beschriebenen Jobs ausgeführt werden:
Im ersten Schritt wird der Quellcode des Repositorys ausgecheckt.
Anschließend authentifizieren wir uns bei der Container-Registry von GitHub Packages. Wie Sie sehen, verwenden wir die zuvor definierte Umgebungsvariable
REGISTRY, die aufghcr.ioverweist – die eigene Registry von GitHub für Container-Images.Als Benutzername für die Authentifizierung dient der Nutzer, der den Workflow gestartet hat. Das sollte mit Ihrem Benutzernamen als Inhaber des Repositorys übereinstimmen. Als Passwort wird
GITHUB_TOKENverwendet, das GitHub-Actions-Workflows automatisch zur Verfügung steht. Sie müssen es also nicht manuell als Secret oder Umgebungsvariable im Repository hinzufügen. Die Anmeldung bei der Registry wird bei Pull Requests übersprungen. Das ist ohnehin nicht erforderlich und könnte bei Pull-Request-CI und Forks sensible Informationen offenlegen.Der letzte Schritt im obigen Codebeispiel extrahiert Metadaten aus dem Image und stellt sie für den Docker-Image-Build bereit (unser nächster und letzter Schritt in diesem Workflow!). Die Metadaten enthalten Informationen zu Tags und Labels, die der Docker-Build-Aktion zur Verfügung gestellt werden. Konkret legt die übergebene Eingabe
imagesden Namen des Docker-Images fest, der als Basis für die Tags dient.
Docker-Image erstellen und in der Container-Registry von GitHub Packages veröffentlichen
Im letzten Schritt wird das Docker-Image erstellt und veröffentlicht. Dafür verwenden wir eine Aktion, die beides in einem Schritt erledigt. Sie werden sehen, dass wir die Eingabe push des Workflows auf eine Bedingung setzen: Das Image wird nur dann in der Registry veröffentlicht, wenn das Ereignis nicht durch einen Pull Request ausgelöst wurde:
Das war’s.
Sobald Sie den Workflow speichern (mit der richtigen Einrückung!) und ausführen, indem Sie ihn in den main-Branch mergen, sollte ein Image erstellt und in der Container-Registry von GitHub Packages veröffentlicht werden.
Wenn alles geklappt hat, sehen Sie das lang ersehnte grüne Häkchen für einen erfolgreichen Job – so wie bei mir:

Wie übertrage ich ein Docker-Image in die Container-Registry von GitHub Packages?
Verwenden Sie die offizielle Docker-GitHub-Aktion docker/build-push-action in Ihrer GitHub-Actions-Workflow-Datei und stellen Sie sicher, dass die Umgebungsvariable REGISTRY auf ghcr.io gesetzt ist.
Docker-Images aus der Container-Registry von GitHub Packages abrufen
Nachdem wir nun ein Docker-Image unseres Projekts in einer öffentlichen Registry veröffentlicht haben, testen wir es, indem wir es in unsere lokale Entwicklungsumgebung abrufen:
Wie gebe ich an, welche Docker-Image-Version abgerufen werden soll?
Der Befehl docker pull nimmt ein zusätzliches Argument im Format <registry>/<user>/<repo>:<image tag> entgegen. Um beispielsweise das Docker-Image-Tag „latest“ des my-nodejs-app image aus der Container-Registry von GitHub Packages abzurufen, verwenden Sie folgenden Befehl: docker pull ghcr.io/lirantal/my-nodejs-app
Juhu, es hat geklappt!
Aber Moment … gibt es keine bessere Möglichkeit, die Docker-Images anzuzeigen, die ich in GitHub Packages übertrage? Hier sind Sie richtig!
Docker-Images in GitHub Packages finden
Wenn Sie Ihr GitHub-Profil aufrufen (zum Beispiel meines unter https://github.com/lirantal?tab=packages), sehen Sie jetzt alle Ihre öffentlich verfügbaren Docker-Images.
Wenn Sie dieser Anleitung gefolgt sind und Ihr eigenes Docker-Image erstellt haben: Können Sie es finden? Hier ist die Seite des Docker-Image-Pakets, das ich im Rahmen der GitHub-Actions-CI des Repositorys in GitHub Packages übertragen habe:

Kein latest-Tag im veröffentlichten Docker-Image?
Wenn Sie versucht haben, das Docker-Image anhand seines Namens abzurufen, ohne ein Docker-Image-Tag für den verwendeten main- oder master-Branch anzugeben, ist Ihnen vielleicht aufgefallen, dass das häufig verwendete Docker-Image-Tag latest nicht verfügbar ist. Das passiert, wenn keine Semver-Tags (semantische Versionierung) übertragen wurden. Wenn Sie in Ihrem eigenen Repository solche Tags übertragen, sollte das Tag verfügbar sein.
Wenn Sie für das veröffentlichte Docker-Image unbedingt den Tag-Alias latest festlegen möchten, können Sie die Metadatenaktion wie folgt aktualisieren (beachten Sie den zusätzlichen mehrzeiligen flavor-Schlüssel):
Beachten Sie jedoch, dass dadurch immer das Image-Tag latest als Alias für das veröffentlichte Docker-Image gesetzt wird, wenn der main-Branch einen CI-Job auslöst.
Wie versehe ich ein Docker-Image mit dem Tag latest?
Um ein zuvor erstelltes Image lokal mit einem Tag zu versehen, verwenden Sie die folgende Syntax für den Docker-Tag-Befehl: docker tag <local image name> <new tag>. Zum Beispiel: docker tag my-nodejs-app lirantal/my-nodejs-app:latest
Wie führe ich ein Docker-Image mit einem Tag aus?
Um beim Ausführen eines Images ein bestimmtes Docker-Image-Tag zu verwenden, geben Sie im Befehl docker run einfach den vollständig qualifizierten Image-Namen und das Tag an. Zum Beispiel: docker run --rm -p 27017:27017 mongo:latest
Relevante Docker- und Container-Integrationen im GitHub Actions Marketplace
Sie können GitHub-Actions-Workflows auch im GitHub Actions Marketplace finden und erstellen. Dort stehen Ihnen mehr als 9.000 Workflows aus den Bereichen Codequalität, Abhängigkeitsverwaltung, Sicherheit und mehr zur Verfügung. Dort finden Sie auch die Snyk GitHub Actions, mit denen Sie Ihre Projekte vor Schwachstellen in Open-Source-Bibliotheken von Drittanbietern schützen und sicherstellen können, dass Ihr Team sichere Programmierpraktiken befolgt.
Für unser Thema – Docker-Images erstellen, testen und in einer Registry veröffentlichen – gibt es einen einfacheren Einstieg als die Suche im Marketplace. Wenn sich bereits eine Dockerfile in Ihrem Repository befindet, erkennt GitHub sie automatisch und schlägt passende Workflows für GitHub Actions vor. Rufen Sie einfach den Tab Actions auf:

Der erste vorgeschlagene Workflow Publish Docker Container richtet einen ähnlichen Workflow zum Erstellen und Veröffentlichen von Docker-Images ein wie der, den wir uns bereits angesehen haben.
Zusammenfassung und nächste Schritte
Habe ich Ihr Interesse an sicheren Entwicklungspraktiken geweckt? Wunderbar! Hier finden Sie einige weiterführende Ressourcen, mit denen Sie loslegen und bei Ihrem Team Sicherheitspunkte sammeln können:
Die Sicherheit der Supply Chain ist wichtig. Hier sind 10 Best Practices für GitHub-Sicherheit, damit Sie nicht dieselben Fehler machen.
Arbeiten Sie mit Node.js und erstellen Sie npm-Pakete? Ich auch! In diesem Beitrag erfahren Sie, wie Sie mit GitHub Actions npm-Pakete sicher veröffentlichen.
Wenn Sie viel im GitHub-Ökosystem arbeiten, sollten Sie sich das Code-Scanning von Snyk ansehen. Es lässt sich nahtloser in Ihre Workflows integrieren: GitHub Security Code Scanning: Schützen Sie Ihre Open-Source-Abhängigkeiten
Starten Sie mit Capture the Flag
Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Herausforderungen lösen.



