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 urspruenglichenDB_ENCRYPTION_KEYwerden 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:
| Feld | Wert |
|---|---|
[email protected] | |
| Passwort | Admin123! |
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:
| Container | Aufgabe | RAM-Verbrauch |
|---|---|---|
postgres | Speichert alle Daten | ~256 MB |
backend | Java-API-Server und Geschaeftslogik | ~512 MB – 1.5 GB |
gotenberg | Wandelt HTML in PDF um (Chromium-basiert) | ~200 MB |
frontend | Liefert 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:
| Secret | Was es schuetzt | Wenn verloren |
|---|---|---|
DB_PASSWORD | Zugriff auf die Datenbank | Wiederherstellbar. Per PostgreSQL-Admin-Tools zuruecksetzbar |
DB_ENCRYPTION_KEY | MFA(TOTP)-Codes, SMTP-Passwort, FX-API-Key und alle PII-Felder, wenn ENCRYPT_PII=true | Dauerhaft unlesbar. Diese Felder lassen sich ohne Originalschluessel nicht entschluesseln |
TIMING_TOKEN_SECRET | Anti-Timing-Angriffstoken | Neu erzeugen. Bestehende Token werden ungueltig, Benutzer muessen sich neu anmelden |
PUBLIC_LINK_PASSWORD_SESSION_SECRET | Sitzungen oeffentlicher Links | Neu 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_KEYschuetzt jedoch Daten im Ruhezustand. Geht er verloren, sind diese Felder dauerhaft verloren. WennENCRYPT_PII=trueaktiv 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
.envin 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
.envniemals 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:
- Erstellen Sie eine neue
.envmit neuen Secrets - Stellen Sie die Datenbank aus dem Backup wieder her (
pg_dump/pg_restore) - Alle Geschaeftsdaten (Kunden, Angebote, Produkte, Benutzer) bleiben vollstaendig zugaenglich
- 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=trueaktiv 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:
- 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
-
Eine Domain mit HTTPS einrichten. Setzen Sie
DOMAINundCORS_ALLOWED_ORIGINSauf Ihre echte Domain. Der Frontend-Container (Caddy) holt automatisch Let’s-Encrypt-Zertifikate. -
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.ymlnoch in.envliegen. - 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.
-
Sichern Sie Ihre
.env-Datei bevor Sie irgendetwas anderes tun. Siehe oben Secrets sicher aufbewahren. -
Aktivieren Sie Datenbank-Backups. Siehe den Leitfaden Backup und Wiederherstellung.
-
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.envbei 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 Secrets —
DB_ENCRYPTION_KEYmuss exakt 64 Hex-Zeichen lang sein.DB_PASSWORDmuss zwischen Backend- und PostgreSQL-Container uebereinstimmen. - Portkonflikt — wenn Port 80 oder 443 bereits belegt ist, aendern Sie das
ports-Mapping indocker-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://localhostauf, nichthttps://, solange keine echte Domain verwendet wird
Admin-Passwort vergessen
Nutzen Sie stattdessen einen nicht-destruktiven Wiederherstellungsweg:
- Wenn SMTP konfiguriert ist, beginnen Sie mit dem Login-Flow Passwort vergessen?
- Wenn sich noch ein anderer Administrator anmelden kann, oeffnen Sie
Usersim Admin-Panel und setzen das Passwort dort zurueck. Administratoren koennen ein neues Passwort setzen und bei Bedarf einen Passwortwechsel beim naechsten Login erzwingen. - 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
- Konfigurationsleitfaden — Branding, E-Mail-Templates, Sicherheitseinstellungen
- Referenz der Umgebungsvariablen — vollstaendiger Katalog der
.env- und Docker-Compose-Variablen - Bereitstellungsoptionen — Coolify, Produktions-Topologie, Backup-Worker
- Backup und Wiederherstellung — automatisierte Backups mit Verschluesselung