Zum Inhalt springen
Q
QuoteNode

Installation

Mit Portainer, QNAP oder NAS installieren

QuoteNode auf einem NAS oder Portainer-verwalteten Docker-Host bereitstellen mit vollständigen Einrichtungsanweisungen.

Mit Portainer, QNAP oder NAS installieren

Verwenden Sie diesen Pfad, wenn Sie Docker über Portainer, QNAP Container Station, Synology oder eine ähnliche Plattform betreiben. Die genaue Benutzeroberfläche unterscheidet sich je nach Anbieter, aber der zugrundeliegende Docker-Compose-Stack ist identisch.

Wann Sie diesen Pfad verwenden

  • Sie betreiben bereits Docker-Stacks über eine Container-Verwaltungsoberfläche.
  • Sie verstehen, wie die Plattform Volumes und Ports mapped.
  • Sie können Backups außerhalb der NAS-Oberfläche verifizieren.

Was möglicherweise nicht funktioniert

  • Öffentliche Links funktionieren außerhalb des LANs nicht, es sei denn, NAT, DNS, Proxy und HTTPS sind konfiguriert.
  • NAS-Schlafmodi können den Dienst unterbrechen.
  • Einige NAS-Docker-Oberflächen schreiben Compose-Dateien oder Umgebungsvariablen um; verifizieren Sie den gerenderten Stack, bevor Sie sich darauf verlassen.
  • Backups, die nur auf demselben NAS gespeichert sind, schützen nicht vor NAS-Ausfall.

Voraussetzungen

  • Docker Compose v2-Unterstützung in Ihrer Plattform.
  • Persistente Volume-Unterstützung für PostgreSQL-Daten, Uploads, PDFs und Backups.
  • Mindestens 2 GB RAM verfügbar und 10 GB freier Festplattenspeicher.
  • Eine stabile URL: LAN-IP für die interne Nutzung oder eine öffentliche Domain hinter einem Reverse-Proxy für Kundenlinks.

Schritt 1 — Konfigurationsdatei erstellen

Erstellen Sie eine .env-Datei (oder setzen Sie Variablen über das Umgebungs-UI Ihrer Plattform). Ersetzen Sie die URL durch Ihre tatsächliche NAS-Adresse oder öffentliche Domain:

Für eine rein interne NAS-Bereitstellung:

# 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 — UNIQUE to this installation.
# 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

# Internal NAS URL
CORS_ALLOWED_ORIGINS=http://nas.local
DOMAIN=nas.local

# 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

Für eine öffentliche Domain hinter einem Reverse-Proxy:

CORS_ALLOWED_ORIGINS=https://crm.example.com
DOMAIN=crm.example.com

Speichern Sie Ihre .env sofort. Wenn Sie DB_ENCRYPTION_KEY verlieren, werden verschlüsselte Felder dauerhaft unlesbar.

Schritt 2 — Docker-Compose-Stack erstellen

Verwenden Sie den Stack-Editor in Portainer oder Ihrer NAS-Docker-Oberfläche, oder erstellen Sie eine docker-compose.yml-Datei:

services:
  postgres:
    image: postgres:18-alpine
    cpus: 4.0
    mem_limit: 512m
    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: 448m
    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: 4.0
    mem_limit: 1792m
    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
    cpus: 2.0
    mem_limit: 192m
    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:

Port-Konflikte: Wenn Ihr NAS bereits Port 80 oder 443 verwendet, ändern Sie die linke Seite des ports-Mappings (z. B. "8080:80") und aktualisieren Sie CORS_ALLOWED_ORIGINS entsprechend (z. B. http://nas.local:8080).

Schritt 3 — Bereitstellen und verifizieren

Starten Sie den Stack über Ihre Plattform-Oberfläche oder via SSH:

docker compose up -d
docker compose logs -f backend

Warten Sie, bis Sie Started QuoteNodeApplication sehen.

Schritt 4 — QuoteNode öffnen

Navigieren Sie zu Ihrer NAS-URL (z. B. http://nas.local oder https://crm.example.com).

Standard-Anmeldedaten:

FeldWert
Email[email protected]
PasswortAdmin123!

Ändern Sie das Standardpasswort sofort nach dem Einloggen.

Persistenz-Checkliste

Stellen Sie sicher, dass diese Daten auf persistenten Volumes gemapped sind (nicht auf ephemeren Container-Speicher):

DatenWarum sie wichtig sind
PostgreSQL dataHauptanwendungsdatenbank
UploadsProduktbilder, Logos, Anhänge
Generated PDFsAngebots- und Dokumentdateien
BackupsLokale Backup-Archive (wenn Backup-Worker aktiviert ist)
GeoIP databaseOptionale Zugriffskontrolldaten

Was läuft gerade?

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.

Secrets sicher aufbewahren

SecretWas es schütztBei Verlust
DB_PASSWORDDatenbankzugangWiederherstellbar — über PostgreSQL-Admintool zurücksetzen
DB_ENCRYPTION_KEYMFA-Codes, SMTP-Passwort, FX-API-Schlüssel, PII-FelderDauerhaft unlesbar
TIMING_TOKEN_SECRETAnti-Timing-Angriff-TokensNeu generieren — Benutzer authentifizieren sich neu
PUBLIC_LINK_PASSWORD_SESSION_SECRETSitzungen für öffentliche LinksNeu generieren — aktive Sitzungen laufen ab

Verwahren Sie .env-Backups außerhalb des NAS. Ein NAS-Ausfall, der Ihre einzige Kopie von DB_ENCRYPTION_KEY zerstört, macht verschlüsselte Daten unwiederbringlich.

Empfohlene nächste Schritte

  • Konfigurieren Sie Backups an einem Ort außerhalb des NAS.
  • Testen Sie die PDF-Generierung nach der ersten Bereitstellung.
  • Wenn Sie einen reibungsloseren öffentlichen Bereitstellungspfad möchten, ziehen Sie Coolify auf einem VPS in Betracht.

Last reviewed: Recently