Git-Server auf der Synology DiskStation via Docker

Ein eigener Git-Server ist schon praktisch. Zwar gibt es diverse frei nutzbare Git-Anbieter im Netz, den eigenen Code vertraut man dann aber anderen an. Dazu kommt noch, dass die kostenlosen Konten meist nur öffentliche Repositories erlauben. Möchte man den Code selbst verwalten, muss man sich einen eigenen Git-Server einrichten. Synologys Paket-Zentrum würde zwar einen Git-Server anbieten, dabei müsste aber der SSH-Zugriff auf die DiskStation verwendet werden, um zu commiten. Möchte man auch von unterwegs auf seine Repositories zugreifen, wäre die DiskStation über das Internet per SSH erreichbar, höchst bedenklich. Hier würde zwar ein VPN Abhilfe schaffen, noch eleganter geht es aber mit Docker. Da der Git-Server im Container läuft, wird Sicherheit erhöht. Der Einsatz von Docker bringt noch einen weiteren Vorteil mit sich: anstelle einer einfachen Git-Installation könnt ihr einen Server ähnlich wie GitLab nutzen und profitiert so zusätzlich zu Git-Repositiries von einem Webinterface inklusive Issue-Tracker und Pull Requests. Ich verwende hierfür die Open-Source-Lösung Gitea.

Vorbereitung

Ihr benötigt eine DiskStation mit installiertem Docker. Einige der schwächeren Modelle bieten Docker nicht im Paket-Zentrum an, da die Leistung nicht ausreicht. Wenn ihr viele Docker-Container betreibt, kann ein RAM-Upgrade eurer DS nicht schaden. Weiters benötigt ihr eine Subdomain um euren Container, durch SSL-Verschlüsselung abgesichert, zu erreichen. Für die Anleitung erzeuge ich ein SSL-Zertifikat von Let’s Encrypt und verwende einen Reverse Proxy. Habt ihr keine eigene Domain, könnt ihr den Server im LAN auch mit einer lokalen Adresse betreiben oder eine DynDNS-Domain verwenden. Ein Let’s Encrypt-Zertifikat bekommt ihr dafür aber keines. Ihr könnt in dem Fall den Container selbst mit einem selbst signierten Zertifikat absichern.

Für den Gitea Container wird empfohlen einen eigenen Benutzer zu verwenden, bzw. scheint es Probleme zu geben, wenn der Container als root ausgeführt wird. Legt in eurer DiskStation also einen neuen Benutzer an. Aus Sicherheitsgründen, sollte dieser keinen Zugriff auf irgendwelche Anwendungen oder Freigabeordner der DiskStation haben (Ausnahmen siehe später). Erstellt am Besten auch eine eigene Benutzergruppe der Ihr den Benutzer zuteilt. Diese Gruppe könnt ihr für andere Docker-Container-Benutzer verwenden, bzw. wenn ihr schon so eine Gruppe habt, benutzt diese.

Installation

Öffnet Docker auf eurer DiskStation und wechselt in den Bereich Registrierung. Gitea benötigt eine Datenbank. Sucht daher nach MariaDB und ladet das neueste Image herunter. Habt ihr bereits ein MariaDB-Image, könnt ihr den Schritt überspringen. Als nächstes, ladet ihr euch noch das Gitea-Image herunter.

MariaDB und Gitea Image
MariaDB und Gitea Image

Als nächstes, richten wir ein eigenes Netzwerk für unsere Source-Code-Verwaltung ein. Wechselt in den Bereich Netzwerk, klickt auf Hinzufügen und gebt einen Namen für das Netzwerk ein, alle weiteren Einstellungen könnt ihr belassen und auf Hinzufügen klicken.

Ein eigenes Docker Netzwerk
Ein eigenes Docker Netzwerk

Datenbank einrichten

Wollt ihr die Datenbank auch bequem per Hyper Backup sichern oder anders auf die Daten zugreifen, ohne den Umweg über Docker zu machen, benötigt ihr dafür einen Ordner auf eurem NAS. Üblicherweise wird dafür den freigegebenen Ordner /docker verwendet. Erstellt dort einen Ordner und gebt ihm beispielsweise den Namen eures MariaDB-Containers. Darin erstellt ihr einen weiteren Ordner und nennt ihn data. Das selbe gilt für Gitea, erstellt also auch dafür einen Ordner und auch darin wieder einen data-Ordner.

Lokale Ordner für die Container-Daten
Lokale Ordner für die Container-Daten

Außerdem müsst ihr die Berechtigungen für den Benutzer festlegen. Dieser sollte möglichst nur auf gitea/data zugreifen dürfen. Wählt dazu den Ordner in der File Station aus und klickt mit Rechts darauf. Unter Einstellungen > Berechtigung klickt ihr auf Erstellen. Im Dropdown wählt ihr jetzt den Benutzer und gebt diesem Lese und Schreibrechte.

Lese und Schreibrechte für den Benutzer in /data-Ordner.
Lese und Schreibrechte für den Benutzer in /data-Ordner.

Wechselt in den Bereich Image und wählt das MariaDB-Image. Klickt auf Ausführen und vergebt einen Namen für den Container (dieser dient innerhalb des Container-Netzwerkes als Hostname) und aktiviert den automatischen Neustart. Klickt anschließend auf Weiter.

Ein neuer MariaDB Container
Ein neuer MariaDB Container

Da ihr MariaDB außerhalb des Docker-Netzwerkes nicht erreichen müsst, könnt ihr die Auswahl auf “Automatisch” belassen. Unter “Volume-Einstellungen” wählt Ordner hinzufügen, wählt den vorhin erstellten Ordner /data und mountet ihn auf /var/lib/mysql. Unter “Umgebung” fügt ihr eine neue Umgebungsvariable hinzu. Der Name der Variable lautet "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" und als Wert gebt ihr 1 ein.

Durch die Verwendung des lokalen Ordners kann der Container leicht gesichert und aktualisiert werden
Durch die Verwendung des lokalen Ordners kann der Container leicht gesichert und aktualisiert werden
Umgebungsvariable für den ersten Start
Umgebungsvariable für den ersten Start

Unter “Netzwerk” wählt im Dropdown das zuvor erstellte Netzwerk aus, klickt anschließend auf Weiter und Fertig.

Jetzt müsst ihr etwas warten, bis der Container gestartet und initialisiert wurde, danach könnt ihr die Installation im Container abschließen. Wechselt in den Bereich Container. Dort seht ihr die laufenden Container. Markiert den MariaDB-Container und klickt auf Details. Wechselt dann in den Reiter Protokoll. Sobald ihr dort die Meldung “[Note] mariadbd: ready for connections" seht, ist der Container einsatzbereit.

Start des Containers abgeschlossen
Start des Containers abgeschlossen

Wechselt in den Reiter Terminal und klickt auf Erstellen und anschließend auf den neuen Eintrag “bash”. Gebt jetzt folgenden Befehl ein:

/bin/mariadb-secure-installation

Da wir dem Container die Variable MARIADB_ALLOW_EMPTY_ROOT_PASSWORD mitgegeben haben, ist der root-Zugang ohne Passwort. Bestätigt die Frage nach dem root-Passwort also mit <Enter>. Die frage nach dem Unix-Socket verneint ihr durch die Eingabe von "n". Die Frage nach dem root-Passwort bestätigt ihr mit "y", gebt anschließend das Passwort ein und bestätigt es durch eine erneute Eingabe.
Das Entfernen des anonymen Users, das Untersagen des Remote-Zugriffs für den root, das Entfernen der Test-Datenbank und das neu Laden der Privilegien-Tabelle bestätigt ihr alles mit "y".

MariaDB Installation
MariaDB Installation

Die Installation von MariaDB ist abgeschlossen. Jetzt müsst ihr für Gitea eine Datenbank samt Benutzer erstellen. Meldet euch dazu im Container-Terminal bei MariaDB an:

mariadb -u root -p

Gebt anschließend das zuvor vergebene Passwort ein. Jetzt könnt ihr mittels SQL-Befehlen Datenbank und Benutzer anlegen:

CREATE DATABASE <DB_NAME>;
CREATE USER '<USER_NAME>'@'%' IDENTIFIED BY '<PASSWORT>';
GRANT ALL PRIVILEGES ON <DB_NAME>.* TO <USER_NAME>@'%';
FLUSH PRIVILEGES;
Vorbereiten von Datenbank und Benutzer
Vorbereiten von Datenbank und Benutzer

Gitea Installieren

Wechselt wieder in den Bereich Image und erstellt einen neuen Container aus dem zuvor heruntergeladenen Gitea-Image. Startet wieder den Container-Assistenten und vergebt Namen und Ressourcen nach Wahl. Im nächsten Fenster müsst Ihr jetzt fixte lokale Ports vergeben, da Ihr auf Gitea ja über den Reverse Proxy zugreifen wollt. Ihr werdet übrigens darauf hingewiesen, sollte ein gewählter Port bereits belegt sein. Generell solltet ihr aber keine häufig genutzten Ports bzw. nicht die Standardports (22 für SSH) verwenden, auch wenn diese auf der DiskStation noch nicht belegt sind. Selbstgewählte Ports sind zwar kein absoluter Schutz, Standardports sind aber viel häufiger Attacken ausgesetzt. Den angelegten /data-Ordner mountet ihr auf /data.

Lokale Ports für den Zugriff und Ordner-Mount für einfache Backups.
Lokale Ports für den Zugriff und Ordner-Mount für einfache Backups.

Unter “Umgebung” müsst Ihr einige Variablen anpassen bzw. hinzufügen. Bei der Variable “USER” gebt ihr den Benutzernamen des Benutzers an, den Ihr zu Beginn für den Container erstellt habt. Außerdem fügt ihr die Variablen “USER_UID” und “USER_GID” hinzu.

Umgebungsvariablen für den Gitea-Container.
Umgebungsvariablen für den Gitea-Container.

Dort müsst ihr die ID des Users bzw. seiner Gruppe einfügen. Um diese herauszufinden müsst ihr per Kommandozeile auf euer NAS zugreifen und dort den Befehl id <Benutzername> eingeben. Wenn Ihr schon die Kommandozeile offen hab, könnt ihr dem Benutzer gleich die Ownership am /data-Ordner geben, das ist wichtig, sonst funktioniert Gitea nicht, der Befehl lautet chown -R <Benutzername>:<Gruppe> /volumeX/docker/gitea/data. Achtet darauf den richtigen Benutzer und Gruppe sowie den Pfad zum /data-Ordner auf eurer DiskStation anzugeben. Alternativ zu Kommandozeile könnt ihr Befehle auch über den Aufgabenmanager ausführen.

Abfrage von UID und GID über die Kommandozeile.
Abfrage von UID und GID über die Kommandozeile.

Wählt auch hier wieder das erstellte Netzwerk aus und schließt den Assistenten ab.

Reverse Proxy

Habt ihr keine eigene Domain, könnt ihr diesen Abschnitt überspringen.

Bevor es auf der DiskStation weitergeht, müsst ihr folgende Schritte durchführen:

  • Erstellt eine Subdomain und last sie auf eure externe, statische IP oder eure DynDNS-Adresse zeigen.
  • Erstellt in eurem Router eine Portfreigabe, entweder auf die zuvor gewählten Ports des Gitea-Containers, oder auf den HTTPS-Port 443 oder einen andern, beliebigen Port. Ihr könnt auch Ports verwenden, die bereits auf eure DiskStation zeigen.

Öffnet auf eurer DiskStation Systemsteuerung > Anmeldeportal > Erweitert > Reverse Proxy. Erstellt einen neuen Eintrag:

  • Vergebt einen Namen.
  • Wählt für die Quelle:
    • HTTPS als Protokoll
    • gebt die vorgesehene Subdomain als Hostnamen ein
    • als Port wählt ihr den freigegebenen Port
    • aktiviert HSTS
  • Wählt für das Ziel:
    • als Hostnamen “localhost”
    • als Port den selbstgewählten Port, den ihr für den Gitea-Container-Port 3000 vergeben habt
Der Reverse Proxy für den Container-Zugriff
Der Reverse Proxy für den Container-Zugriff

Klickt auf Speichern. Wollt ihr später auch den SSH-Zugang verwenden, müsst ihr einen weiteren Reverse Proxy einrichten. Diese muss dann einen weiteren Quellport auf den Port mappen, den ihr für den Container-Port 22 verwendet habt. Subdomain kann dabei gleich bleiben. Generell kann eine Kombination aus Hostname und Port immer nur ein einziges Mal existieren. Mehr dazu im letzten Abschnitt.

Fordert jetzt für die Subdomain ein SSL-Zertifikat an und weist das Zertifikat dem Reverse Proxy zu (unter Systemsteuerung > Sicherheit > Zertifikat > Einstellungen).

Weiter mit Gitea

Jetzt könnt ihr Gitea im Browser aufrufen. Ihr erreicht den Container entweder mit dem eingerichteten Reverse Proxy oder aber der IP bzw. der Domain unter der ihr eure DiskStation erreich sowie den gewählten Port (den, den ihr auf 3000 gemappt habt). Verwendet ihr einen Reverse Proxy und den HTTPS-Port 443, müsst ihr die Portnummer nicht extra angeben.

Klickt rechts oben auf Anmelden und ihr werdet zum Installationsassistenten weitergeleitet. Dort müsst ihr folgende Angaben machen:

  • Datenbanktyp: MySQL
  • Host: <MariaDB_Containername>:3306 (hier müsst ihr den Containerport vom MariaDB-Container verwenden, da ja beide Container im selben Docker-Netzwerk laufen)
  • Benutzername: Den angelegten Datenbankbenutzer
  • Passwort: Das verwendete Benutzerpasswort, nicht das für den root
  • Datenbankname: den Namen der angelegten Datenbank
  • SSH-Server-Domain: gebt hier die Subdomain ein, die ihr für den SSH-Zugriff verwenden wollt, entweder die Domain die ihr für den Reverse Proxy (mit dem SSH Port) genutzt habt, die Domain oder die IP eurer DiskStation; Beispiel: 192.168.0.11:57022 oder gitserver.mydomain.com
  • Gitea-Basis-URL: gebt hier die Domain ein mit der ihr Gitea im Browser bzw. ohne SSH aufrufen wollt, entweder die Domain die ihr für den Reverse Proxy (mit dem Port 3000) genutzt habt, die Domain oder die IP eurer DiskStation; Beispiel: http://192.168.0.11:57030 oder https://gitserver.mydomain.com
  • E-Mail-Einstellungen und Sonstige Server- und Drittserviceeinstellungen nach Bedarf, hier wäre es ratsam das Registrieren neuer User zu deaktivieren, sofern sich Aufrufer nicht selbst registrieren sollen
  • Unter Administratoreinstellungen legt ihr euren Benutzer für Gitea an
Datenbankangaben für Gitea
Datenbankangaben für Gitea
URL- und POort-Einstellungen von Gitea
URL- und Port-Einstellungen von Gitea

Klickt jetzt auf Gitea installieren und wartet den Installationsprozess ab, dies kann eine Weile dauern.

Et voilà, Ihr habt euren eigenen Git-Server im Container auf eurer DiskStation laufen. Ihr könnt im Webinterface jetzt Repositories anlegen und über die URL über die Git-Commandline oder dem Git-Client eurer Wahl darauf zugreifen.

Sicherheit

Noch ein paar Worte zum Thema Sicherheit.

Wollt ihr den Git-Server von außen nicht erreichbar machen, aber nicht die lokale Adresse eurer DS verwenden, könnt ihr eine lokale Sub-Domain verwenden (per Hosts-Datei oder DNS auf der DiskStation). Damit könnt ihr dann ebenfalls einen Reverse Proxy einrichten.

Wollt ihr eure Sub-Domain + SSL-Zertifikat verwenden, den Server aber nicht im Internet freigeben, habt ihr mehrere Möglichkeiten das umzusetzen. Ihr könnt beispielsweise nach Anfordern des Zertifikats die Portfreigabe im Router herausnehmen bzw. in der Verwaltung eurer Domain die Zuweisung der Sub-Domain auf eure externe IP/DynDNS-Domain entfernen (am besten ihr macht beides davon). Alternativ könnt ihr auch in der Firewall eurer DiskStation den Zugriff auf den Reverse Proxy nur im LAN erlauben. Läuft das Zertifikat ab, müsst ihr die externe Verbindung aber wieder herstellen, um das Zertifikat erneuern zu können. Als Alternative könnt ihr noch für den Reverse Proxy ein eigenes Zugangskontrollprofil einrichten, eine separate Firewall, die nur für den Reverse Proxy gilt. Das ist vorallem dann praktisch, wenn ihr mehrere Reverse Proxys mit Quell-Port 443 verwenden wollt. Durch Verwendung von 443 als Quell-Port erspart man sich

WICHTIG: Der MariaDB-Container ist nicht ausschließlich aus dem Docker-Netzwerk erreichbar, ihr könnt ihn über den lokalen Port auch aus dem LAN und unter Umständen sogar aus dem Internet erreichen. Habt ihr meine Anweisungen befolgt, kann man sich als root nur direkt innerhalb des Containers (Terminal in Docker) anmelden. Der erstellte Benutzer kann sich aber – durch die Angabe % beim Erstellen – von überall aus einloggen. Ihr habt mehrere Möglichkeiten diese Absicherung vorzunehmen.

Ihr könnt zuerst die IP-Adresse des Gitea-Containers abfragen (Docker > Gitea > Terminal und dort ip address eingeben). Den angelegten Benutzer wieder löschen und einen neuen Benutzer erstellen. Benutzt dazu die selben Befehle wie oben, ersetzt % aber durch die IP des Gitea-Containers.

Alternativ dazu könnt ihr in der DS-Firewall den lokalen Port des Maria-DB-Containers blockieren (dazu müsst ihr aber einen manuell zuweisen, stoppt dazu den Container und geht auf Bearbeiten).

Habt ihr eure Firewall ordentlich konfiguriert und erlaubt nur explizit erlaubte Verbindungen (Whitelist) ist das ganze kein Problem, da die Verbindung sowieso nicht erlaubt ist.

Möchtet Ihr noch detailliertere Schritt-Für-Schritt-Anleitungen für euer Synology NAS, mit viel mehr Hintergrundinformationen, Tipps und Tricks? Dann holt euch mein Wissen als als umfassendes Praxis-Handbuch. Mehr Infos findet ihr in keinem Buch zu Synology und alles in der von mir gewohnten Qualität.

Die dritte Auflage enthält Aktualisierungen zu DSM 7.1 und den Updates von WebStation, Surveillance Station und Synology Photos.

Das Buch direkt beim Verlag

Das Buch auf Amazon

Related Posts

3 thoughts on “Git-Server auf der Synology DiskStation via Docker

  1. Sorry. One more update. The new docker container of mariadb has no mysql cilent on it. Now use mariadb instead.
    So not [mysql -u root -p] but [mariadb -u root -p] works!

  2. the script for secure install in mariadb is now at [/bin/mariadb-secure-installation] not [/usr/bin/mysql_secure_installation]

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert