Zum Inhalt springen
Q
QuoteNode

Installation

Auf einem Ubuntu-Oeffentlichserver installieren

QuoteNode auf einem öffentlichen Ubuntu-Server mit Domain, HTTPS, SMTP, Backups und Firewall-Grundlagen bereitstellen.

Auf einem Ubuntu-Oeffentlichserver installieren

Verwenden Sie diesen Pfad für eine Produktionsbereitstellung, die von Kunden über eine öffentliche Domain erreichbar ist.

Wann Sie diesen Pfad verwenden

  • Externe Kunden müssen öffentliche Angebotslinks öffnen können.
  • E-Mail-Nachrichten sollen funktionierende Links enthalten.
  • Sie möchten direkte Kontrolle über den Server statt einer PaaS-Schicht.

Was ohne ordentliche Konfiguration nicht funktioniert

  • Öffentliche Links schlagen fehl, wenn DNS nicht auf den Server zeigt.
  • Öffentliche Links schlagen fehl, wenn die Browser-URL von der CORS-Konfiguration abweicht.
  • HTTPS-Zertifikat-Ausstellung schlägt fehl, wenn Ports 80/443 blockiert sind.
  • E-Mail-Links schlagen fehl, wenn SMTP fehlt oder Nachrichten vom Mail-Provider des Empfängers abgelehnt werden.
  • Dynamische Heim-IP-Bereitstellungen benötigen DDNS und Router-Port-Weiterleitung; ein VPS ist normalerweise einfacher.

Voraussetzungen

  • Ubuntu LTS-Server oder VPS.
  • Öffentlicher DNS-Eintrag, zum Beispiel crm.example.com, der auf den Server zeigt.
  • Ports 80 und 443 aus dem Internet geöffnet.
  • Docker Engine 24.0+ und Docker Compose v2.
  • SMTP-Konto für E-Mail-Zustellung.
  • Mindestens 4 GB RAM und 20 GB freier Festplattenspeicher (empfohlen für Produktion).
  • Backup-Ziel und ein Wiederherstellungsverfahren.

Docker überprüfen:

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 crm.example.com durch Ihre echte Domain:

# 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

# Public domain — replace with your real domain
CORS_ALLOWED_ORIGINS=https://crm.example.com
DOMAIN=crm.example.com

# Email delivery
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME[email protected]
SMTP_PASSWORD=your-smtp-password
SMTP_AUTH=true
SMTP_STARTTLS=true

# Notification preference links (must match your public domain)
NOTIFICATIONS_PUBLIC_PREFERENCES_URL=https://crm.example.com/notifications/preferences

# 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

Sichern Sie Ihre .env-Datei vor dem ersten Produktionseinsatz. Speichern Sie sie in einem Passwort-Manager oder einem physischen Safe. Der DB_ENCRYPTION_KEY ist entscheidend — sein Verlust bedeutet, dass verschlüsselte Daten für immer weg sind.

SMTP-Alternative: Sie können die SMTP_*-Variablen aus .env weglassen und E-Mail später unter Einstellungen > E-Mail-SMTP in QuoteNode konfigurieren. Das Admin-Panel speichert das SMTP-Passwort verschlüsselt mit DB_ENCRYPTION_KEY, sodass es nicht in Ihrer .env-Datei stehen muss.

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 — Firewall konfigurieren

Öffnen Sie nur das, was benötigt wird:

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Stellen Sie PostgreSQL nicht öffentlich dar. Es bleibt im Docker-Netzwerk.

Schritt 5 — QuoteNode starten

docker compose up -d

Beobachten Sie den Startvorgang:

docker compose logs -f backend

Warten Sie, bis Sie Started QuoteNodeApplication sehen. Der Frontend-Container (Caddy) bezieht automatisch ein Let’s Encrypt-Zertifikat für Ihre Domain.

Schritt 6 — QuoteNode öffnen

Navigieren Sie zu https://crm.example.com in Ihrem Browser.

Standard-Anmeldedaten:

FeldWert
Email[email protected]
PasswortAdmin123!

Ändern Sie das Standardpasswort sofort nach dem Einloggen.

Prüfung nach der Bereitstellung

  1. Einloggen und Admin-Passwort ändern.
  2. Ein Test-Angebot erstellen.
  3. Ein PDF generieren.
  4. Einen öffentlichen Link erstellen und von einem anderen Gerät öffnen.
  5. Wenn SMTP konfiguriert ist, eine Test-Benachrichtigung senden und prüfen, ob die E-Mail-Links funktionieren.

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 (Caddy mit Auto-HTTPS)~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

Upgrade-Checkliste

Vor jedem Upgrade:

  1. Bestätige die aktuelle App-Version im Admin-Bereich.
  2. Sichere .env.
  3. Führe ein neues Backup aus oder verifiziere es.
  4. Lade die neuen Images herunter und starte neu.
  5. Überprüfe Backend-Gesundheit, Login, PDF-Generierung und einen öffentlichen Angebotslink.

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 in einem Passwort-Manager (1Password, Bitwarden). Für maximale Sicherheit drucken Sie die Secrets aus und bewahren den Ausdruck in einem physischen Safe auf. Committen Sie .env niemals in die Versionsverwaltung.

Wiederherstellung bei Verlust von .env

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

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

Last reviewed: Recently