Kategorien
Angular

Privates NPM Repository mit Verdaccio (SSL, Docker) – Teil 2: Serverinstallation mit Docker und SSL

Als Angular Entwickler stellt man schnell fest, dass sich viele Components / Modules / Directives / Services & Co. in mehreren Projekten wiederverwenden lassen. Da bietet sich natürlich ein eigenes privates Repository zum Hosten und Bereitstellen von NPM Packages an.

Bei Zotorn IT haben wir uns derzeit für die open source Lösung Verdaccio (https://verdaccio.org/, https://github.com/verdaccio/verdaccio) entschieden. Verdaccio kann man kinderleicht aufsetzen und konfigurieren.

Der Artikel besteht insgesamt aus 4 Teilen:

  1. Lokale Arbeitsplatzinstallation
  2. Serverinstallation mit Docker und SSL
  3. Handhabung Verdaccio & npm
  4. Verdaccio absichern

Teil 2: Serverinstallation mit Docker und SSL

Wenn dir der lokale Arbeitsplatz nicht ausreicht oder du die Registry einem ganzen Team zur Verfügung stellen willst, dann kannst du Verdaccio natürlich auch auf einem Server installieren. Andernfalls kannst diesen Teil überspringen und direkt zu Teil 3 übergehen.

Vorraussetzungen für diesen Artikel

  • vom Internet erreichbarer Server mit Linux und Docker
  • ein wenig Dockererfahrung
  • Eine Domain oder Subdomain, die auf die Server IP zeigt

Werbung

Hier bei Zotorn IT haben wir alle Registries (Docker, NPM, Maven, etc.) auf einen Rootserver gepackt. Wir haben uns hierbei für ein Produkt von NetCup entschieden:
Produkt: RS 1000 SAS G8, 320GB HDD, 8GB RAM, derzeit ab 6,99€/Monat
320 GB HDD reichen absolut für unsere Repositories aus und mit den 8GB RAM läuft auch Docker einwandfrei in einem Swarm Cluster. Prozessorleistung spielt für einen Repository-Server keine wirkliche Rolle.

Weitere Infos: https://www.netcup.de/bestellen/produkt.php?produkt=2103 (Werbelink, Provision)
Gutscheincode 5 Euro (fuer Neukunden, keine Domains): 36nc15817836860, 36nc15817836861, 36nc15817841470
Gutscheincode 30% Rabatt RS 1000 SAS G8: 2201nc15817841100, 2201nc15817977670, 2201nc15817977950
Sag uns einfach kurz Bescheid, wenn die Gutscheine nicht mehr funktionieren und aufgebraucht sind, wir haben noch ein paar auf Lager für dich.

SSL Zertifikat

Als Erstes benötigen wir ein SSL Zertifikat, damit wir die Kommunikation zwischen Server und Client absichern können. Wir verwenden ein kostenloses Zertifikat von Let's Encrypt.

Mit dem certbot lassen sich kinderleicht Let's Encrypt Zertifikate managen und weil wir keine Lust haben, auf jedem Server certbot zu installieren, verwenden wir einfach das offizielles certbot Docker Image, um unser Zertifikat zu verwalten. Das Image hat als Entrypoint certbot, was bedeutet, dass wir einfach nur noch ein paar Parameter an den docker run Befehl packen, die direkt an cerbot weitergeben werden:

docker pull certbot/certbot

# DEINE_DOMAIN (2x) und DEINE_EMAIL (1x) ersetzen nicht vergessen.
# Die Reihenfolge der Parameter ist wichtig!
docker run --rm \
        -p 80:80 \
        -v registry_letsencrypt_etc:/etc/letsencrypt \
        certbot/certbot \
        certonly --standalone \
        -d DEINE_DOMAIN \
        --cert-name DEINE_DOMAIN \
        --non-interactive \
        --agree-tos \
        --email DEINE_EMAIL

Was passiert hier?

  • docker run --rm Standard Docker run Befehl, --rm entfernt den Container nach dem Durchlauf automatisch
  • -p 80:80 Damit die Let's Encrypt Registrierungsstelle alles prüfen kann, musst der Webserver Port 80 nach außen offen und nicht belegt (Apache?) sein.
  • -v registry_letsencrypt_etc:/etc/letsencrypt Damit wir das Zertifikat auch mit anderen Containern nutzen können, muss es in einem (named) Volume abgespeichert werden.
  • certbot/certbot Das Certbot Docker Image
  • certonly Das ist der erste Parameter, der nicht an docker run, sondern an certbot übergeben wird, daher Reihenfolge beachten. Wir benötigen nur ein Zertifikat.
  • --standalone Die Verifizierung soll über den integrierten standalone Webserver (auf Port 80) stattfinden.
  • -d DEINE_DOMAIN Domainname
  • --cert-name DEINE_DOMAIN Zertifikatsname. Am besten den Domainnamen verwenden, das vermeidet Verwirrung.
  • --non-interactive Da wir keine weiteren Eingaben an den Container übergeben können, muss alles ohne Rückfragen ablaufen
  • --agree-tos Wir müssen den Terms of Service von Let's Encrypt zustimmen, die wir natürlich bereits gelesen haben.
  • --email DEINE_EMAIL Außerdem wird noch eine E-Mail-Adresse verlangt

Hoffentlich hat alles geklappt, und es erscheint in etwa folgende Meldung:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/DEINE_DOMAIN/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/DEINE_DOMAIN/privkey.pem
   Your cert will expire on 2020-05-16. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Docker speichert auf Linux seine Named-Volumes unter /var/lib/docker/volumes, daher kannst du dir dein Zertifikat wie folgt ausgeben lassen:

cat /var/lib/docker/volumes/registry_letsencrypt_etc/_data/live/DEINE_DOMAIN/cert.pem

Output:
-----BEGIN CERTIFICATE-----
MIIFUDCCBDigAwIBAgISAyzVwcTSMR3FOJCTGa5GAHRaMA0GCSqGSIb3DQEBCwUA
....
k5zCuq332wIxkbzTOAcwLZcICdU=
-----END CERTIFICATE-----

Verdaccio mit SSL Zertifikat starten

Zuerst kopieren wir den Inhalt der standard docker.yaml Konfigurationsdatei für Verdaccio in eine neue Datei mit dem Namen config.yaml. Diese bearbeiten wir dann wie folgt:

# /dein/pfad/zur/config.yaml
......
# Am Ende der Datei einfügen und DEINE_DOMAIN ersetzen nicht vergessen
https:
  key: /etc/letsencrypt/live/DEINE_DOMAIN/privkey.pem
  cert: /etc/letsencrypt/live/DEINE_DOMAIN/cert.pem
  ca: /etc/letsencrypt/live/DEINE_DOMAIN/fullchain.pem

Verdaccio starten

Jetzt starten wir nur noch Verdaccio als Docker Container:

docker pull verdaccio/verdaccio

# /dein/pfad/zur/config.yaml entsprechend anpassen
docker run -d --rm \
--name "verdaccio" \
--user=0 \
-e VERDACCIO_PROTOCOL=https \
-p 4873:4873 \
-v /dein/pfad/zur/config.yaml:/verdaccio/conf/config.yaml:ro \
-v verdaccio_npm_storage:/verdaccio/storage \
-v verdaccio_npm_plugins:/verdaccio/plugins \
-v registry_letsencrypt_etc:/etc/letsencrypt:ro \
verdaccio/verdaccio

  • docker run --rm Docker run Befehl
  • --name "verdaccio" Der Docker Container soll den Namen "verdaccio" bekommen.
  • --user=0 Das Verdaccio Image läuft normal mit dem verdaccio User, welcher die ID 10001 hat. Da wir aber das Volume registry_letsencrypt_etc mounten, welches nur mit root Rechten einsehbar ist, müssen wir dafür sorgen, dass Verdaccio auch mit Root-Rechten läuft. Das erzeugt beim Start folgende Warnung: *** WARNING: Verdaccio doesn't need superuser privileges. Don't run it under root! ***. Jetzt kann man an dieser Stelle natürlich einiges unternehmen, damit das Zertifikat auch für normale User lesbar ist. Bspw. Zertifikat kopieren, Rechte ändern und kopiertes Zertifikat mounten. Oder direkt die Rechte für das Zertifikat ändern. Das sind aber alles Änderungen auf Hosting Maschine, welche ich immer nach Möglichkeit vermeide, wenn Docker im Spiel ist. Soll sich der Container darum kümmern. Außerdem läuft Verdaccio isoliert in einem Docker Container und wir mounten das Zertifikat mit :ro im Read-Only-Modus. Es besteht also keine Gefahr durch einen außer Kontrolle geratenen Verdaccio Server.
  • -e VERDACCIO_PROTOCOL=https Wir schalten den https Modus ein.
  • -p 4873:4873 Port nach außen öffnen.
  • -v /dein/pfad/zur/config.yaml:/verdaccio/conf/config.yaml:ro Unsere bearbeitete Config im Read-Only-Modus mounten.
  • -v verdaccio_npm_storage:/verdaccio/storage Ein Storage Volume mounten, in dem Verdaccio alles abspeichert.
  • -v verdaccio_npm_plugins:/verdaccio/plugins Pluginsverzeichnis, falls wir später Plugins hinzufügen möchten.
  • -v registry_letsencrypt_etc:/etc/letsencrypt:ro Das certbot Verzeichnis mit dem Zertifikat, ebenfalls im Read-Only-Modus.

Um den Container für den Livebetrieb im Hintergrund zu starten, einfach docker run -d für detached verwenden.

Die Registry sollte jetzt unter https://DEINE_DOMAIN:4873 erreichbar sein:

Bleibt noch zu erwähnen, dass alle Let's Encrypt Zertifikate nach 90 Tagen ablaufen und erneuert werden müssen. Daher kann ich folgendes Shell-Script empfehlen, welches alle ein bis zwei Wochen per Cronjob ausgeführt werden sollte.

#!/bin/sh

# Erneuert automatisch alle Zertifikate, welche älter als 60 Tage sind
docker run \
    --rm \
    -p 80:80 \
    -v registry_letsencrypt_etc:/etc/letsencrypt \
    zotornit/certbot:latest renew

# Verdaccio mit dem erneuerten Zertifikat neustarten
docker container restart verdaccio

weiter zu Teil 3 - Handhabung Verdaccio & npm