Files
moneyfy/docs/deployment.md
T
Jonas MenzelandClaude Opus 5 c110340628
CI / backend (push) Successful in 2m49s
Images bauen / build (frontend) (push) Successful in 3m12s
Images bauen / build (backend) (push) Successful in 3m22s
CI / frontend (push) Successful in 6m20s
feat: Kommando zum Setzen des Passworts
Die Erstanlage beim Start greift nur, solange die Benutzertabelle leer ist. Wer
.env.example zuerst unverändert übernimmt, bekommt einen Benutzer mit dem
Platzhalter; ein späteres Ändern von MONEYFY_ADMIN_PASSWORD bleibt danach
wirkungslos. Das Kommando setzt das Passwort direkt, legt den Benutzer bei
Bedarf an und beendet alle offenen Sitzungen.

docs/deployment.md nennt jetzt die drei Ursachen einer fehlgeschlagenen
Anmeldung in der Reihenfolge ihrer Häufigkeit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014e7t8UpmoVNMtWivY5LiSH
2026-09-09 23:40:42 +02:00

7.5 KiB
Raw Blame History

Betrieb auf docker-srv001

Erstinstallation

mkdir -p /opt/moneyfy && cd /opt/moneyfy

# docker-compose.yml und .env.example aus dem Repository holen
curl -fsSLO https://git.menzel.center/menzeljonas/moneyfy/raw/branch/main/docker-compose.yml
curl -fsSLO https://git.menzel.center/menzeljonas/moneyfy/raw/branch/main/.env.example
cp .env.example .env

In .env mindestens setzen:

POSTGRES_PASSWORD=$(openssl rand -hex 24)
SECRET_KEY=$(openssl rand -hex 32)
MONEYFY_ADMIN_PASSWORD=<Startpasswort>
PUBLIC_BASE_URL=https://moneyfy.menzel.center
TAG=latest

Das externe Proxy-Netz muss existieren NPMplus bringt es üblicherweise mit:

docker network inspect proxy >/dev/null 2>&1 || docker network create proxy

An der Registry anmelden und starten:

docker login git.menzel.center
docker compose up -d
docker compose logs -f moneyfy-backend

Das Backend wartet auf die Datenbank, spielt die Migrationen ein und legt beim allerersten Start den Kategoriebaum an. Danach ist die Oberfläche unter http://127.0.0.1:8087 erreichbar.

Beim ersten Anmelden gelten MONEYFY_ADMIN_USER und MONEYFY_ADMIN_PASSWORD; die Anwendung verlangt sofort ein neues Passwort. Danach kann MONEYFY_ADMIN_PASSWORD aus der .env entfernt werden.

NPMplus konfigurieren

moneyfy.menzel.center als Proxy Host anlegen:

Feld Wert
Domain Names moneyfy.menzel.center
Scheme http
Forward Hostname / IP moneyfy-frontend
Forward Port 8080
Cache Assets aus der Container setzt die Cache-Kopfzeilen selbst
Block Common Exploits an
Websockets Support aus die Anwendung braucht keine

Unter SSL: Zertifikat über Let's Encrypt anfordern, Force SSL und HTTP/2 einschalten, HSTS aktivieren.

Damit NPMplus den Container über seinen Namen erreicht, müssen beide im Netz proxy liegen. Das erledigt docker-compose.yml bereits; prüfen mit:

docker network inspect proxy --format '{{range .Containers}}{{.Name}} {{end}}'

Unter Advanced diese Zusatzkonfiguration eintragen. Sie sorgt dafür, dass die Anwendung das richtige Schema sieht und Exporte nicht in einen Timeout laufen:

proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host  $host;
client_max_body_size 4m;
proxy_read_timeout 120s;

Die Anmeldung setzt Secure-Cookies. Ohne HTTPS also ohne Zugriff über NPMplus kommt keine Sitzung zustande. Für einen Test über http://127.0.0.1:8087 muss COOKIE_SECURE=false gesetzt werden.

Aktualisieren

Das Ausrollen passiert bewusst von Hand; die CI baut nur die Images.

cd /opt/moneyfy

# Bei fester Version: TAG in .env auf die neue Version setzen.
docker compose pull
docker compose up -d
docker compose logs -f moneyfy-backend

Die Migrationen laufen beim Start des Backends automatisch. Ein Blick in die Ausgabe zeigt, welche Revision eingespielt wurde.

Zurückrollen: TAG auf die vorherige Version setzen und erneut docker compose up -d. Achtung: Migrationen werden dabei nicht rückgängig gemacht. Vor einem Update mit Schemaänderung immer erst sichern.

Sicherung

Zwei Dinge müssen gesichert werden: die Datenbank und das Volume mit den Logos.

Datenbank

docker compose exec -T moneyfy-db \
  pg_dump -U moneyfy -d moneyfy --format=custom \
  > /var/backups/moneyfy/db-$(date +%F).dump

Wiederherstellen:

docker compose stop moneyfy-backend
docker compose exec -T moneyfy-db \
  pg_restore -U moneyfy -d moneyfy --clean --if-exists < /var/backups/moneyfy/db-2026-03-01.dump
docker compose start moneyfy-backend

Logo-Volume

docker run --rm \
  -v moneyfy-data:/data:ro \
  -v /var/backups/moneyfy:/backup \
  alpine tar czf /backup/logos-$(date +%F).tar.gz -C /data .

Wiederherstellen:

docker run --rm \
  -v moneyfy-data:/data \
  -v /var/backups/moneyfy:/backup \
  alpine sh -c "rm -rf /data/* && tar xzf /backup/logos-2026-03-01.tar.gz -C /data"

Die Logos lassen sich zur Not auch neu beschaffen die Datenbank nicht.

Tägliche Sicherung per Cron

/opt/moneyfy/backup.sh:

#!/bin/sh
set -eu

ZIEL=/var/backups/moneyfy
TAG=$(date +%F)
mkdir -p "$ZIEL"

cd /opt/moneyfy
docker compose exec -T moneyfy-db \
  pg_dump -U moneyfy -d moneyfy --format=custom > "$ZIEL/db-$TAG.dump"

docker run --rm \
  -v moneyfy-data:/data:ro \
  -v "$ZIEL:/backup" \
  alpine tar czf "/backup/logos-$TAG.tar.gz" -C /data .

# Älteres als 30 Tage entfernen.
find "$ZIEL" -name 'db-*.dump' -mtime +30 -delete
find "$ZIEL" -name 'logos-*.tar.gz' -mtime +30 -delete
30 3 * * * /opt/moneyfy/backup.sh >> /var/log/moneyfy-backup.log 2>&1

Die Sicherungen anschließend auf ein anderes System spiegeln eine Kopie auf demselben Host hilft bei einem Plattenausfall nicht.

Fehlersuche

Backend startet nicht, Log endet bei „Warte auf die Datenbank“ Die Datenbank ist nicht gesund. docker compose ps und docker compose logs moneyfy-db prüfen; meist stimmt POSTGRES_PASSWORD in der .env nicht mit dem im Volume hinterlegten Passwort überein. Ein bereits angelegtes Volume übernimmt kein neues Passwort.

SECRET_KEY ist nicht gesetzt Die Anwendung verweigert in Produktion den Start mit dem Platzhalterwert. openssl rand -hex 32 erzeugt einen passenden Schlüssel. Wird er später geändert, sind alle Sitzungen ungültig das ist beabsichtigt.

Anmeldung schlägt fehl

Drei Ursachen kommen in Frage, in dieser Reihenfolge prüfen:

  1. Der Benutzer wurde mit einem anderen Passwort angelegt. Die Erstanlage greift nur, solange die Benutzertabelle leer ist. Wer .env.example zuerst unverändert übernimmt und startet, bekommt einen Benutzer mit dem Platzhalter ein späteres Ändern von MONEYFY_ADMIN_PASSWORD bleibt dann wirkungslos. Abhilfe:

    docker compose exec moneyfy-backend python -m app.scripts.reset_password \
      --username admin --password "neues-passwort"
    
  2. Der Container kennt den neuen Wert noch nicht. docker compose restart behält die alte Umgebung. Nach einer Änderung an der .env muss der Container neu erstellt werden:

    docker compose up -d --force-recreate moneyfy-backend
    docker compose exec moneyfy-backend printenv MONEYFY_ADMIN_PASSWORD
    
  3. Kein HTTPS. Die Cookies sind Secure gesetzt und erreichen den Server über eine reine HTTP-Verbindung nicht. Typisches Bild: die Anmeldung meldet keinen Fehler, landet aber sofort wieder auf der Anmeldemaske. Entweder über NPMplus zugreifen oder für einen Test COOKIE_SECURE=false setzen.

Welcher Fall vorliegt, verrät das Log:

docker compose logs moneyfy-backend | grep -iE "administrator|MONEYFY_ADMIN"

Firmen bekommen kein Logo Ohne Netzzugang findet nur der lokale Markenkatalog etwas; unbekannte Firmen erhalten einen erzeugten Avatar. Das ist so gewollt. Mit docker compose exec moneyfy-backend python -c "from app.services.logos import simple_icon_index; print(simple_icon_index().version)" lässt sich prüfen, ob der Katalog im Image liegt.

Keine Benachrichtigungen SCHEDULER_ENABLED und NOTIFICATIONS_ENABLED prüfen, dann in der Oberfläche unter Einstellungen → Benachrichtigungen den Einrichtungsstand ansehen und eine Testnachricht schicken. Das Versandprotokoll steht auf derselben Seite.

Speicherplatz

docker system df
docker compose exec moneyfy-db psql -U moneyfy -d moneyfy -c "\l+"
docker run --rm -v moneyfy-data:/data:ro alpine du -sh /data