6.4 KiB
HCRB auf dem eigenen Server betreiben (Docker + Nginx Proxy Manager)
Annahme: ein Linux-Server mit SSH-Zugang und Docker, auf dem der Nginx Proxy Manager (NPM) als Container läuft
und die Domains verwaltet. Dazu eine (Sub-)Domain, z. B. hcrb.example.de.
Der Ablauf: Code liegt in einem Git-Repository → Server holt ihn per git pull → docker compose baut und startet
den Container → der Container hängt im selben Docker-Netz wie NPM → NPM leitet die Domain per HTTPS an hcrb:3000.
Die Daten (data/) liegen außerhalb des Containers auf dem Server und bleiben bei Updates erhalten.
1. Git-Repository ✓
Erledigt – der Code liegt in https://github.com/guyg1474/hcrb (privat).
data/, .env und node_modules/ stehen in .gitignore – Passwörter und Mitgliederdaten landen nicht im Repository.
2. Domain
Beim Domain-Anbieter einen A-Record (und ggf. AAAA für IPv6) für hcrb.example.de auf die IP des Servers setzen
(wie bei den anderen Domains, die schon über NPM laufen).
3. Code auf den Server holen (einmalig)
Per SSH auf dem Server. Zugriff auf das private Repository – einen SSH-Schlüssel erzeugen:
ssh-keygen -t ed25519 -N "" -f ~/.ssh/hcrb_deploy
cat ~/.ssh/hcrb_deploy.pub
Den ausgegebenen Schlüssel im Repository unter Settings → Deploy keys eintragen (nur Lesezugriff). Dann:
sudo mkdir -p /opt/hcrb && sudo chown $USER: /opt/hcrb
GIT_SSH_COMMAND="ssh -i ~/.ssh/hcrb_deploy" git clone git@github.com:guyg1474/hcrb.git /opt/hcrb
cd /opt/hcrb
git config core.sshCommand "ssh -i ~/.ssh/hcrb_deploy"
chmod +x deploy/*.sh
# Datenordner – der Container läuft als Benutzer "node" (UID 1000) und muss hier schreiben dürfen
mkdir -p data && sudo chown 1000:1000 data
4. Mit dem Netz des Nginx Proxy Managers verbinden
Der HCRB-Container wird in das Docker-Netz gehängt, in dem NPM schon läuft. Am NPM selbst muss nichts geändert werden.
Name des NPM-Containers und seines Netzes herausfinden:
docker ps --format '{{.Names}}\t{{.Image}}' | grep -i nginx-proxy-manager
docker inspect NAME-DES-NPM-CONTAINERS --format '{{range $k, $v := .NetworkSettings.Networks}}{{$k}} {{end}}'
Die zweite Zeile gibt den Netzwerknamen aus, z. B. npm_default. Diesen in die Datei .env eintragen:
cp .env.example .env
nano .env # PROXY_NETWORK=npm_default (durch den ausgegebenen Namen ersetzen)
5. Daten übernehmen (optional)
Wer die bisherigen Mitglieder, Termine und Logins mitnehmen will, kopiert sie vom eigenen Rechner:
# lokal ausführen
scp data/db.json data/users.json DEIN-USER@SERVER:/tmp/
# auf dem Server
sudo mv /tmp/db.json /tmp/users.json /opt/hcrb/data/
sudo chown 1000:1000 /opt/hcrb/data/*.json && sudo chmod 600 /opt/hcrb/data/*.json
6. Container starten
cd /opt/hcrb
docker compose up -d --build
docker compose ps # Status sollte nach ca. 30 Sekunden "Up … (healthy)" zeigen
Ohne übernommene Daten jetzt den ersten Login anlegen (Passwort wird verdeckt abgefragt):
docker compose exec hcrb npm run user -- add elias
Prüfen, ob NPM den Container erreicht (sollte {"user":null} ausgeben):
docker exec NAME-DES-NPM-CONTAINERS curl -s http://hcrb:3000/api/me
Der Container startet automatisch neu – nach Abstürzen und nach einem Server-Neustart (restart: unless-stopped).
7. Domain im Nginx Proxy Manager anlegen
In der NPM-Weboberfläche: Hosts → Proxy Hosts → Add Proxy Host
Reiter Details
| Feld | Wert |
|---|---|
| Domain Names | hcrb.example.de |
| Scheme | http |
| Forward Hostname / IP | hcrb |
| Forward Port | 3000 |
| Cache Assets | aus |
| Block Common Exploits | an |
| Websockets Support | aus (wird nicht gebraucht) |
Reiter SSL
| Feld | Wert |
|---|---|
| SSL Certificate | Request a new SSL Certificate |
| Force SSL | an |
| HTTP/2 Support | an |
| HSTS Enabled | an |
| E-Mail / Agree to Terms | ausfüllen bzw. anhaken |
Speichern – NPM holt das Zertifikat und verlängert es automatisch. Danach ist die Seite unter
https://hcrb.example.de erreichbar.
NPM gibt die echte Besucher-IP und das Protokoll (X-Forwarded-For, X-Forwarded-Proto) von sich aus weiter –
das braucht die Seite für die Sperre nach 10 falschen Passwörtern und für das sichere Login-Cookie.
Unter Advanced muss dafür nichts eingetragen werden.
Hinweis: Port 3000 wird bewusst nicht nach außen freigegeben – die Seite ist nur über NPM erreichbar. Die NPM-Oberfläche (Port 81) sollte ebenfalls nicht offen im Internet stehen.
8. Backups
sudo crontab -e
# Zeile hinzufügen:
30 3 * * * /opt/hcrb/deploy/backup.sh
Sichert täglich um 3:30 Uhr data/ nach /var/backups/hcrb/ und behält 30 Tage.
Am besten zusätzlich ab und zu eine Sicherung vom Server herunterladen.
Änderungen aufspielen (jedes Mal)
# lokal
git add .
git commit -m "Was geändert wurde"
git push
# auf dem Server
ssh DEIN-USER@SERVER /opt/hcrb/deploy/update-docker.sh
update-docker.sh holt den neuen Stand, baut den Container neu und startet ihn. Die Daten bleiben unverändert,
an NPM muss nichts geändert werden.
Nützliche Befehle auf dem Server
Alle im Ordner /opt/hcrb ausführen:
| Zweck | Befehl |
|---|---|
| Status | docker compose ps |
| Log ansehen | docker compose logs -f |
| Neu starten | docker compose restart |
| Stoppen / Starten | docker compose down / docker compose up -d |
| Benutzer anlegen | docker compose exec hcrb npm run user -- add <name> |
| Passwort ändern | docker compose exec hcrb npm run user -- passwd <name> |
| Benutzer auflisten | docker compose exec hcrb npm run user -- list |
| Backup zurückspielen | docker compose down && sudo tar -xzf /var/backups/hcrb/hcrb-DATUM.tar.gz -C /opt/hcrb && sudo chown -R 1000:1000 data && docker compose up -d |
Fehlersuche
| Problem | Ursache / Lösung |
|---|---|
network … declared as external, but could not be found |
Netzwerkname in .env stimmt nicht – Schritt 4 wiederholen. |
| NPM zeigt „502 Bad Gateway“ | Container läuft nicht (docker compose ps, docker compose logs) oder hängt nicht im NPM-Netz (Schritt 4). |
Container startet neu mit EACCES … data |
Rechte am Datenordner: sudo chown -R 1000:1000 /opt/hcrb/data |
| Nach 10 falschen Passwörtern ist der Login für alle gesperrt | Die Seite erkennt die echte Besucher-IP nicht – prüfen, ob TRUST_PROXY in docker-compose.yml gesetzt ist und der Zugriff über NPM erfolgt. |