Zum Inhalt springen
Q
QuoteNode

Installation

Auf einem Linux LAN-Server installieren

QuoteNode auf einem internen Linux-Server für ein Büro- oder VPN-only-Team ausführen.

Auf einem Linux LAN-Server installieren

Verwenden Sie diesen Pfad, wenn QuoteNode auf einem internen Linux-Server, einer VM oder einem Mini-PC laufen soll, der vom Büronetzwerk oder VPN erreichbar ist.

Wann Sie diesen Pfad verwenden

  • Mehrere interne Benutzer benötigen eine stabile gemeinsame Instanz.
  • Öffentlicher Kundenzugriff ist nicht erforderlich.
  • Sie bevorzugen einen Linux-Host gegenüber Docker Desktop.

Was nicht funktionieren wird

  • Öffentliche Angebotslinks funktionieren nur für Benutzer, die die Serveradresse erreichen können.
  • E-Mail-Zustellung kann mit SMTP funktionieren, aber Empfänger außerhalb des LANs können interne Links nicht öffnen.
  • Selbstsigniertes internes HTTPS kann Browser-Warnungen anzeigen, es sei denn, Ihre Organisation vertraut der Zertifizierungsstelle.

Voraussetzungen

  • Ubuntu, Debian oder eine andere gepflegte Linux-Distribution.
  • Docker Engine 24.0+ und Docker Compose v2.
  • Eine statische IP oder DHCP-Reservierung für den Server.
  • SSH-Zugang für Betreiber.
  • Mindestens 2 GB RAM und 10 GB freier Festplattenspeicher.
  • Backup-Speicher außerhalb des Haupt-Docker-Volumes.

Ü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. Ersetzen Sie 192.168.1.20 durch die tatsächliche LAN-IP Ihres Servers oder den internen DNS-Namen (z. B. crm.internal):

# 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

# LAN URL — replace with your server IP or internal DNS name
CORS_ALLOWED_ORIGINS=http://192.168.1.20
DOMAIN=192.168.1.20

# 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

Wenn Sie hinter einem internen Reverse-Proxy mit HTTPS bereitstellen, verwenden Sie stattdessen den HTTPS-Ursprung:

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

Speichern Sie Ihre .env-Datei sofort. Verwahren Sie eine Kopie außerhalb dieses Servers. Wenn Sie DB_ENCRYPTION_KEY verlieren, werden verschlüsselte Felder dauerhaft unlesbar.

Schritt 3 — Docker-Compose-Datei erstellen

Erstellen Sie eine Datei namens docker-compose.yml:

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:

Schritt 4 — QuoteNode starten

docker compose up -d

Docker lädt die Container-Images beim ersten Start herunter. Beobachten Sie den Startvorgang:

docker compose logs -f backend

Warten Sie, bis Sie Started QuoteNodeApplication sehen.

Schritt 5 — QuoteNode öffnen

Navigieren Sie zu http://192.168.1.20 (oder Ihrer Serveradresse) von einem beliebigen Gerät im LAN.

Standard-Anmeldedaten:

FeldWert
Email[email protected]
PasswortAdmin123!

Ändern Sie das Standardpasswort sofort nach dem Einloggen.

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.

Häufige Befehle

# Check service status
docker compose ps

# View logs
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

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

Das kritische Secret ist DB_ENCRYPTION_KEY. Verwahren Sie .env-Backups außerhalb dieses Servers. Weitere Wiederherstellungsschritte finden Sie unter Installations-Fehlerbehebung.

Empfohlene nächste Schritte

  • Konfigurieren Sie geplante Backups und testen Sie eine Wiederherstellung.
  • Testen Sie die PDF-Generierung nach der ersten Bereitstellung.
  • Verwenden Sie Ubuntu-Oeffentlichserver oder Coolify, wenn öffentliche Angebotslinks für Kunden funktionieren müssen.

Last reviewed: Recently