Zum Inhalt springen
Q
QuoteNode

Installation

Auf einem lokalen Laptop installieren

QuoteNode lokal zur Evaluierung ausführen, ohne es für Kunden zugänglich zu machen.

Auf einem lokalen Laptop installieren

Verwenden Sie diesen Pfad, wenn Sie QuoteNode auf einem Computer ausprobieren möchten. Es ist der schnellste Weg, die Anwendung zu evaluieren, aber keine kundenseitige Bereitstellung.

Wann Sie diesen Pfad verwenden

  • Sie möchten eine Demo- oder Testinstanz.
  • Sie testen Angebotserstellung, PDFs, Vorlagen, Produkte und Einstellungen.
  • Kunden müssen keine öffentlichen Angebotslinks von einem anderen Gerät öffnen.

Was nicht funktionieren wird

  • Öffentliche Angebotslinks, die als http://localhost/... generiert werden, funktionieren nur auf demselben Laptop.
  • E-Mail-Links sind meist nicht nützlich, weil Empfänger localhost nicht von ihren Geräten öffnen können.
  • HTTPS ist für diese Topologie normalerweise nicht konfiguriert.
  • Der Laptop muss eingeschaltet sein und Docker muss laufen.

Voraussetzungen

  • Docker Desktop oder Docker Engine mit Docker Compose v2.
  • Mindestens 2,5 GB RAM, die für den Stack verfügbar sind.
  • Mindestens 10 GB freier Festplattenspeicher.

Überprüfen Sie Ihre Konfiguration:

docker --version        # Should show 24.0+
docker compose version  # Should show v2.x

Schritt 1 — Projektverzeichnis erstellen

mkdir quotenode && cd quotenode

Schritt 2 — Konfigurationsdatei erstellen

Erstellen Sie eine Datei namens .env mit den minimalen Pflichteinstellungen. Generieren Sie Ihre eigenen Secrets — verwenden Sie die Platzhalterwerte nicht in der Produktion:

# Database
DB_URL=jdbc:postgresql://postgres:5432/quotenode
DB_USERNAME=quotenode
DB_PASSWORD=change-me-to-something-random-32-chars
DB_NAME=quotenode

# ============================================================
# SECURITY SECRETS — READ THIS BEFORE CONTINUING
# These values are UNIQUE to your installation.
# If you lose this file, you CANNOT regenerate the same secrets.
# SAVE THIS FILE and keep a secure backup.
# ============================================================
DB_ENCRYPTION_KEY=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
TIMING_TOKEN_SECRET=change-me-timing-secret-min-32-chars
PUBLIC_LINK_PASSWORD_SESSION_SECRET=change-me-session-secret-min-32

# Domain (for CORS and Caddy)
CORS_ALLOWED_ORIGINS=http://localhost
DOMAIN=localhost

# Die Client-IP wird hinter internen Proxys und CDNs (auch Cloudflare) automatisch erkannt — leer lassen.
# Nur für ein ungewöhnliches Proxy setzen, dessen Transport-Peer eine ÖFFENTLICHE Adresse ist (IP/CIDR oder Hostname).
SECURITY_TRUSTED_PROXIES=

# Application
LOG_LEVEL=INFO
SPRING_PROFILES_ACTIVE=prod

Speichern Sie Ihre .env-Datei sofort. Der DB_ENCRYPTION_KEY verschlüsselt sensible Daten im Ruhezustand. Wenn Sie ihn verlieren, werden verschlüsselte Felder (MFA-Codes, SMTP-Passwort, API-Schlüssel) dauerhaft unlesbar. Kopieren Sie diese Datei an einen sicheren Ort.

Schritt 3 — Docker-Compose-Datei erstellen

Erstellen Sie eine Datei namens docker-compose.yml:

services:
  postgres:
    image: postgres:18-alpine
    cpus: 2.0
    mem_limit: 384m
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      PGDATA: /var/lib/postgresql/data   # required for the postgres:18 image
    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
    cpus: 2.0
    mem_limit: 384m
    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
    cpus: 2.0
    mem_limit: 1280m
    depends_on:
      postgres: { condition: service_healthy }
      gotenberg: { condition: service_healthy }
    env_file: .env
    environment:
      SPRING_PROFILES_ACTIVE: prod
      # Single-container eval (WEB_MAINTENANCE backup profile): the backend runs
      # scheduled backups in-process, so no separate backup-worker container is needed.
      # For production, split into a web backend + a dedicated backup-only worker.
      JOBS_MODE: all
      BACKUP_RUNTIME_PROFILE: WEB_MAINTENANCE
      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
    cpus: 1.0
    mem_limit: 128m
    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 lädt die Container-Images herunter (beim ersten Start dauert das einige Minuten). Beobachten Sie den Startvorgang:

docker compose logs -f backend

Warten Sie, bis Sie Started QuoteNodeApplication sehen — das bedeutet, dass das Backend bereit ist.

Schritt 5 — QuoteNode öffnen

Navigieren Sie zu http://localhost in Ihrem Browser.

Standard-Anmeldedaten:

FeldWert
Email[email protected]
PasswortAdmin123!

Ändern Sie das Standardpasswort sofort nach dem Einloggen (Einstellungen > Mein Profil > Passwort ändern).

Was läuft gerade?

Nach docker compose up laufen 4 Container:

ContainerAufgabeRAM-Verbrauch
postgresSpeichert alle Ihre Daten~256 MB
backendJava-API-Server, Geschäftslogik~512 MB – 1,5 GB
gotenbergKonvertiert HTML zu PDF (Chromium-basiert)~200 MB
frontendStellt die Web-UI bereit + Reverse Proxy~20 MB

Gesamt: ungefähr 1,5 – 2,5 GB RAM.

Häufige Befehle

# Check if all services are running
docker compose ps

# View logs (all services)
docker compose logs -f

# View logs (backend only)
docker compose logs -f backend

# Stop QuoteNode
docker compose down

# Update to the latest version
docker compose pull && docker compose up -d

Secrets sicher aufbewahren

Ihre .env-Datei enthält kryptografische Secrets, die einzigartig für Ihre Installation sind:

SecretWas es schütztBei Verlust
DB_PASSWORDDatenbankzugangWiederherstellbar — über PostgreSQL-Admintool zurücksetzen
DB_ENCRYPTION_KEYMFA-Codes, SMTP-Passwort, FX-API-Schlüssel und alle PII-Felder wenn ENCRYPT_PII=trueDauerhaft unlesbar — ohne den Originalschlüssel nicht entschlüsselbar
TIMING_TOKEN_SECRETAnti-Timing-Angriff-TokensNeu generieren — bestehende Tokens ungültig, Benutzer authentifizieren sich neu
PUBLIC_LINK_PASSWORD_SESSION_SECRETSitzungen für öffentliche LinksNeu generieren — aktive Sitzungen laufen ab, Links funktionieren weiterhin

Das kritische Secret ist DB_ENCRYPTION_KEY. Alle anderen Secrets können mit kleinen Umständen neu generiert werden. Aber DB_ENCRYPTION_KEY verschlüsselt Daten im Ruhezustand — sein Verlust bedeutet, dass diese Felder für immer weg sind.

Wiederherstellung bei Verlust von .env

Wenn Sie Ihre .env-Datei verlieren, aber ein unverschlüsseltes Datenbank-Backup haben (der Standard-Backup-Modus):

  1. Erstellen Sie eine neue .env mit neuen Secrets.
  2. Stellen Sie die Datenbank aus Ihrem Backup wieder her.
  3. Alle Geschäftsdaten (Kunden, Angebote, Produkte, Benutzer) sind vollständig zugänglich.
  4. Nur wenige Felder gehen verloren: MFA-Codes (Benutzer registrieren sich erneut), SMTP-Passwort (in den Einstellungen neu eingeben), FX-API-Schlüssel (in den Einstellungen neu eingeben). Wenn ENCRYPT_PII=true aktiviert war, gehen auch verschlüsselte Kundendaten verloren.

Backups

Dieses Setup mit einem einzigen Container führt geplante Backups innerhalb des Backend-Prozesses aus (JOBS_MODE: all), sodass Sie keinen separaten backup-worker-Container benötigen. Das Backup selbst läuft als Shell-Pipeline (pg_dump → Komprimierung → Verschlüsselung) außerhalb der JVM, daher ist sein Speicherbedarf gering — deshalb ist das Backend auf dem Laptop mit 1280m statt 1g dimensioniert.

Das ist für einen Laptop oder eine Evaluierungsinstanz akzeptabel. Für eine Produktionsbereitstellung betreiben Sie einen dedizierten backup-only-Worker-Container (JOBS_MODE: backup-only) neben einem Web-Backend (JOBS_MODE: web), damit Backups nie mit dem Web-Traffic um Speicher konkurrieren. Siehe Backup & Wiederherstellung.

Vom Laptop auf einen Server umziehen

Veröffentlichen Sie keine Laptop-Links für Kunden. Wenn Sie bereit für eine gemeinsame oder öffentliche Bereitstellung sind, wählen Sie einen dieser Pfade:

Last reviewed: Recently