Zum Inhalt springen
Q
QuoteNode

Einrichtung

Installationsleitfaden

Wie Sie QuoteNode mit Docker Compose auf Ihrer eigenen Infrastruktur bereitstellen.

Installation

QuoteNode laeuft als Satz von Docker-Containern. Sie muessen weder Java, Node.js noch PostgreSQL direkt auf Ihrer Maschine installieren. Docker uebernimmt alles.

Voraussetzungen

  • Docker Engine 24.0 oder neuer (Docker installieren)
  • Docker Compose v2 (in modernen Docker-Desktop- und Docker-Engine-Installationen enthalten)
  • Eine Maschine mit mindestens 2 GB RAM und 10 GB freiem Speicherplatz

So pruefen Sie Ihre Umgebung:

docker --version        # Sollte 24.0+ anzeigen
docker compose version  # Sollte v2.x anzeigen

Schnellstart (5 Minuten)

Die folgenden Schritte starten QuoteNode lokal zu Evaluierungszwecken. Nicht fuer Produktion. Fuer den Produktionseinsatz gelten zusaetzliche Anforderungen, siehe weiter unten.

Schritt 1 — Projektverzeichnis anlegen

mkdir quotenode && cd quotenode

Schritt 2 — Konfigurationsdatei anlegen

Erstellen Sie eine Datei namens .env mit den minimal erforderlichen Einstellungen:

# Datenbank
DB_URL=jdbc:postgresql://postgres:5432/quotenode
DB_USERNAME=quotenode
DB_PASSWORD=ersetzen-sie-dies-durch-ein-zufaelliges-passwort-mit-32-zeichen
DB_NAME=quotenode

# ============================================================
# SICHERHEITSSECRETS — BITTE VOR DEM WEITERMACHEN LESEN
# Diese Werte sind EINZIGARTIG fuer Ihre Installation.
# Wenn Sie diese Datei verlieren, koennen Sie dieselben Secrets NICHT neu erzeugen.
# SPEICHERN SIE DIE DATEI und legen Sie ein sicheres Backup an.
# ============================================================
DB_ENCRYPTION_KEY=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
TIMING_TOKEN_SECRET=ersetzen-sie-dies-durch-ein-timing-secret-mit-mindestens-32-zeichen
PUBLIC_LINK_PASSWORD_SESSION_SECRET=ersetzen-sie-dies-durch-ein-session-secret-mit-mindestens-32-zeichen

# Domain (fuer CORS und Caddy)
CORS_ALLOWED_ORIGINS=http://localhost
DOMAIN=localhost

# Logging
LOG_LEVEL=INFO
SPRING_PROFILES_ACTIVE=prod

Speichern Sie Ihre .env-Datei sofort. Die oben gezeigten Secrets sind einzigartig fuer diese Installation. Wenn Sie die Datei verlieren, koennen Sie diese Werte nicht identisch wiederherstellen. Ohne den urspruenglichen DB_ENCRYPTION_KEY werden verschluesselte Daten (MFA-Codes, SMTP-Passwort, API-Schluessel) dauerhaft unlesbar. Legen Sie die Datei an einem sicheren Ort ab. Fuer Produktivsysteme empfiehlt sich zusaetzlich ein physischer Ausdruck in einem sicheren Aufbewahrungsort.

Schritt 3 — Docker-Compose-Datei anlegen

Erstellen Sie eine Datei namens docker-compose.yml:

services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME}"]
      interval: 10s
      timeout: 5s
      retries: 10
    restart: unless-stopped

  gotenberg:
    image: gotenberg/gotenberg:8
    environment:
      LOG_LEVEL: info
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:3000/health"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  backend:
    image: ghcr.io/lesisty7/quotenode/quotenode-api:latest
    depends_on:
      postgres: { condition: service_healthy }
      gotenberg: { condition: service_healthy }
    env_file: .env
    environment:
      SPRING_PROFILES_ACTIVE: prod
      JOBS_MODE: web
      PDF_ENABLED: "true"
      PDF_GOTENBERG_URL: http://gotenberg:3000
    volumes:
      - backend_uploads:/app/data/uploads
      - backend_pdfs:/app/data/pdfs
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 45s
    restart: unless-stopped

  frontend:
    image: ghcr.io/lesisty7/quotenode/quotenode-frontend:latest
    depends_on:
      backend: { condition: service_healthy }
    ports:
      - "80:80"
      - "443:443"
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:80/"]
      interval: 15s
      timeout: 5s
      retries: 3
    restart: unless-stopped

volumes:
  postgres_data:
  backend_uploads:
  backend_pdfs:

Schritt 4 — QuoteNode starten

docker compose up -d

Docker laedt die Container-Images herunter. Beim ersten Lauf dauert das einige Minuten. Danach werden alle Dienste gestartet. Sie koennen den Startvorgang verfolgen mit:

docker compose logs -f backend

Warten Sie, bis eine Zeile wie Started QuoteNodeApplication erscheint. Dann ist das Backend betriebsbereit.

Schritt 5 — QuoteNode oeffnen

Oeffnen Sie http://localhost im Browser.

Standard-Zugangsdaten:

FeldWert
E-Mail[email protected]
PasswortAdmin123!

Aendern Sie das Standardpasswort sofort nach dem ersten Login (Einstellungen > Mein Profil > Passwort aendern).

Was laeuft jetzt?

Nach docker compose up sind vier Container aktiv:

ContainerAufgabeRAM-Verbrauch
postgresSpeichert alle Daten~256 MB
backendJava-API-Server und Geschaeftslogik~512 MB – 1.5 GB
gotenbergWandelt HTML in PDF um (Chromium-basiert)~200 MB
frontendLiefert Web-UI und Reverse Proxy aus~20 MB

In Summe: ungefaehr 1.5 – 2.5 GB RAM.

Haeufige Befehle

# Pruefen, ob alle Dienste laufen
docker compose ps

# Logs aller Dienste anzeigen
docker compose logs -f

# Nur Backend-Logs anzeigen
docker compose logs -f backend

# QuoteNode stoppen
docker compose down

# Auf die neueste Version aktualisieren
docker compose pull && docker compose up -d

Secrets sicher aufbewahren

Ihre .env-Datei enthaelt kryptografische Secrets, die einzigartig fuer Ihre Installation sind. Wenn Sie verstehen, was jedes Secret schuetzt, laesst sich Ihre Backup-Strategie sauber planen:

SecretWas es schuetztWenn verloren
DB_PASSWORDZugriff auf die DatenbankWiederherstellbar. Per PostgreSQL-Admin-Tools zuruecksetzbar
DB_ENCRYPTION_KEYMFA(TOTP)-Codes, SMTP-Passwort, FX-API-Key und alle PII-Felder, wenn ENCRYPT_PII=trueDauerhaft unlesbar. Diese Felder lassen sich ohne Originalschluessel nicht entschluesseln
TIMING_TOKEN_SECRETAnti-Timing-AngriffstokenNeu erzeugen. Bestehende Token werden ungueltig, Benutzer muessen sich neu anmelden
PUBLIC_LINK_PASSWORD_SESSION_SECRETSitzungen oeffentlicher LinksNeu erzeugen. Aktive Sitzungen laufen ab, Links selbst funktionieren weiter

Das kritische Secret ist DB_ENCRYPTION_KEY. Alle anderen Secrets lassen sich mit ueberschaubarem Aufwand neu erzeugen. DB_ENCRYPTION_KEY schuetzt jedoch Daten im Ruhezustand. Geht er verloren, sind diese Felder dauerhaft verloren. Wenn ENCRYPT_PII=true aktiv war, betrifft das auch saemtliche personenbezogenen Daten von Kunden, Kontakten, Lieferanten und Benutzern (Namen, E-Mails, Telefonnummern, Steuernummern). Ohne aktivierte PII-Verschluesselung bleiben Geschaeftsdaten unverschluesselt gespeichert und zugaenglich.

Fuer Produktivsysteme empfehlen wir:

  • Legen Sie eine Kopie von .env in einem Passwortmanager ab (1Password, Bitwarden und aehnliche Tools)
  • Fuer maximale Sicherheit drucken Sie die Secrets aus und verwahren sie in einem physischen Safe
  • Committen Sie .env niemals in Versionskontrolle

Wiederherstellung, wenn .env verloren geht

Wenn Sie Ihre .env-Datei verlieren, aber ein unverschluesseltes Datenbank-Backup haben, also den Standard-Backupmodus, koennen Sie Ihre Daten wiederherstellen:

  1. Erstellen Sie eine neue .env mit neuen Secrets
  2. Stellen Sie die Datenbank aus dem Backup wieder her (pg_dump / pg_restore)
  3. Alle Geschaeftsdaten (Kunden, Angebote, Produkte, Benutzer) bleiben vollstaendig zugaenglich
  4. Nur wenige Felder gehen verloren: MFA-Codes (Benutzer muessen neu einrichten), SMTP-Passwort (neu in den Einstellungen eintragen), FX-API-Key (neu eintragen). Falls ENCRYPT_PII=true aktiv war, gehen zusaetzlich alle personenbezogenen Daten verloren (Namen, E-Mails, Telefonnummern, Steuernummern). Das sollte vor Aktivierung der PII-Verschluesselung bewusst abgewogen werden.

Falls Ihre Backups ueber BACKUP_GPG_RECIPIENT mit GPG verschluesselt sind, benoetigen Sie zuerst den privaten GPG-Schluessel zur Entschluesselung.

Produktivbereitstellung

Fuer den Produktionseinsatz muessen Sie:

  1. Saubere Secrets erzeugen. Verwenden Sie niemals die Beispielwerte von oben in Produktion:
# 64-stelligen Hex-Schluessel fuer Datenbankverschluesselung erzeugen
openssl rand -hex 32

# Zufaellige Secrets fuer Token generieren
openssl rand -base64 32
  1. Eine Domain mit HTTPS einrichten. Setzen Sie DOMAIN und CORS_ALLOWED_ORIGINS auf Ihre echte Domain. Der Frontend-Container (Caddy) holt automatisch Let’s-Encrypt-Zertifikate.

  2. E-Mail konfigurieren. Waehlen Sie einen dieser zwei Wege:

  • Bevorzugt: SMTP spaeter in Einstellungen > Email SMTP innerhalb von QuoteNode konfigurieren. Im aktuellen Anwendungscode werden tenant-spezifische SMTP-Einstellungen in der Datenbank gespeichert und das Passwort vor dem Speichern verschluesselt. Dadurch muss das Mail-Passwort weder in docker-compose.yml noch in .env liegen.
  • Fallback: Wenn SMTP schon vor dem ersten Admin-Login vollstaendig bereitstehen soll, setzen Sie es in .env:
SMTP_HOST=smtp.ihranbieter.de
SMTP_PORT=587
SMTP_USERNAME=[email protected]
SMTP_PASSWORD=ihr-smtp-passwort
SMTP_AUTH=true
SMTP_STARTTLS=true

Wenn Sie den Weg ueber das Admin-Panel waehlen, sichern Sie DB_ENCRYPTION_KEY besonders sorgfaeltig. Das gespeicherte SMTP-Passwort wird mit demselben Anwendungsschluessel verschluesselt.

  1. Sichern Sie Ihre .env-Datei bevor Sie irgendetwas anderes tun. Siehe oben Secrets sicher aufbewahren.

  2. Aktivieren Sie Datenbank-Backups. Siehe den Leitfaden Backup und Wiederherstellung.

  3. Pruefen Sie alle Einstellungen. Nutzen Sie die Wiki-Seite Referenz der Umgebungsvariablen fuer die vollstaendige Liste aller Applikations-, Deployment- und Entwicklungsvariablen.

Fuer fortgeschrittene Deployment-Optionen (Coolify PaaS, Backup-Worker, GeoIP) siehe die Wiki-Seite Bereitstellungsoptionen.

QuoteNode aktualisieren

So aktualisieren Sie auf die neueste Version:

docker compose pull && docker compose up -d

Ihre .env-Datei wird durch Updates niemals veraendert. Docker zieht neue Container-Images, aber Ihre Konfiguration und Daten bleiben unberuehrt. Loeschen oder erzeugen Sie .env bei Updates nicht neu. Dieselben Secrets muessen ueber die gesamte Lebensdauer Ihrer Installation hinweg bestehen bleiben.

Datenbankmigrationen laufen beim Start des Backends automatisch. Ein manueller Migrationsschritt ist nicht notwendig.

Fehlerbehebung

Backend startet nicht

Pruefen Sie die Logs mit docker compose logs backend. Typische Ursachen:

  • Datenbank noch nicht bereit — das Backend wartet, bis PostgreSQL gesund ist. Wenn PostgreSQL langsam startet, versucht das Backend automatisch erneut.
  • Ungueltige SecretsDB_ENCRYPTION_KEY muss exakt 64 Hex-Zeichen lang sein. DB_PASSWORD muss zwischen Backend- und PostgreSQL-Container uebereinstimmen.
  • Portkonflikt — wenn Port 80 oder 443 bereits belegt ist, aendern Sie das ports-Mapping in docker-compose.yml.

Keine Verbindung zu QuoteNode moeglich

  • Pruefen Sie mit docker compose ps, ob alle Container laufen
  • Stellen Sie sicher, dass der Frontend-Container als “healthy” gemeldet wird
  • Rufen Sie fuer lokale Tests http://localhost auf, nicht https://, solange keine echte Domain verwendet wird

Admin-Passwort vergessen

Nutzen Sie stattdessen einen nicht-destruktiven Wiederherstellungsweg:

  1. Wenn SMTP konfiguriert ist, beginnen Sie mit dem Login-Flow Passwort vergessen?
  2. Wenn sich noch ein anderer Administrator anmelden kann, oeffnen Sie Users im Admin-Panel und setzen das Passwort dort zurueck. Administratoren koennen ein neues Passwort setzen und bei Bedarf einen Passwortwechsel beim naechsten Login erzwingen.
  3. Wenn sich kein Administrator mehr anmelden kann und der E-Mail-Reset nicht verfuegbar ist, behandeln Sie den Fall als Operator-Recovery-Vorfall. Stellen Sie den Zugriff aus einem bekannten guten Backup wieder her oder nutzen Sie das interne Wartungsverfahren fuer diese Umgebung.

docker compose down -v ist keine Passwort-zuruecksetzen-Prozedur. Der Befehl erstellt die gesamte Instanz neu und loescht alle persistenten Daten, darunter Benutzer, Angebote, Kunden, Einstellungen und lokal gespeicherte Backups. Verwenden Sie ihn nur in entbehrlichen lokalen Testumgebungen, wenn Sie die Instanz bewusst komplett zuruecksetzen wollen.

Siehe auch: Passwort zuruecksetzen und Backup und Wiederherstellung.

Naechste Schritte

Last reviewed: Recently