Przejdź do treści
Q
QuoteNode

Installation

Instalacja na serwerze Linux w sieci LAN

Uruchom QuoteNode na wewnętrznym serwerze Linux dla biura lub zespołu z dostępem tylko przez VPN.

Instalacja na serwerze Linux w sieci LAN

Wybierz tę ścieżkę, gdy QuoteNode ma działać na wewnętrznym serwerze Linux, maszynie wirtualnej lub mini-PC dostępnym w sieci biurowej lub przez VPN.

Kiedy użyć

  • Kilku wewnętrznych użytkowników potrzebuje stabilnej wspólnej instancji.
  • Publiczny dostęp klientów nie jest wymagany.
  • Preferujesz hosta Linux zamiast Docker Desktop.

Co nie zadziała

  • Publiczne linki do ofert działają tylko dla użytkowników, którzy mogą dotrzeć do adresu serwera.
  • Wysyłka e-mail może działać z SMTP, ale odbiorcy spoza LAN nie otworzą wewnętrznych linków.
  • Wewnętrzny HTTPS z self-signed certyfikatem może wyświetlać ostrzeżenia przeglądarki.

Wymagania

  • Ubuntu, Debian lub inna utrzymywana dystrybucja Linux.
  • Docker Engine 24.0+ i Docker Compose v2.
  • Statyczne IP lub rezerwacja DHCP dla serwera.
  • Dostęp SSH dla operatorów.
  • Co najmniej 2 GB RAM i 10 GB wolnego miejsca na dysku.
  • Miejsce na kopie zapasowe poza głównym wolumenem Docker.

Sprawdź konfigurację:

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

Krok 1 — Utwórz katalog projektu

mkdir quotenode && cd quotenode

Krok 2 — Utwórz plik konfiguracyjny

Utwórz plik .env. Zamień 192.168.1.20 na rzeczywisty adres IP serwera lub wewnętrzną nazwę DNS (np. 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

# IP klienta jest wykrywane automatycznie za wewnętrznymi proxy i CDN (w tym Cloudflare) — zostaw puste.
# Ustaw tylko dla nietypowego proxy, którego peer transportowy ma adres PUBLICZNY do zaufania (IP/CIDR lub nazwa hosta).
SECURITY_TRUSTED_PROXIES=

# Application
LOG_LEVEL=INFO
SPRING_PROFILES_ACTIVE=prod

Jeśli wdrażasz za wewnętrznym reverse proxy z HTTPS, użyj adresu HTTPS:

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

Zapisz plik .env natychmiast. Przechowuj kopię poza tym serwerem. Utrata DB_ENCRYPTION_KEY oznacza trwałą utratę zaszyfrowanych pól.

Krok 3 — Utwórz plik Docker Compose

Utwórz plik 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:

Krok 4 — Uruchom QuoteNode

docker compose up -d

Obserwuj postęp uruchamiania:

docker compose logs -f backend

Poczekaj aż zobaczysz Started QuoteNodeApplication.

Krok 5 — Otwórz QuoteNode

Przejdź do http://192.168.1.20 (lub adresu Twojego serwera) z dowolnego urządzenia w sieci LAN.

Domyślne dane logowania:

PoleWartość
Email[email protected]
HasłoAdmin123!

Zmień domyślne hasło natychmiast po zalogowaniu.

Co działa?

KontenerFunkcjaUżycie RAM
postgresPrzechowuje wszystkie dane~256 MB
backendSerwer API Java, logika biznesowa~512 MB – 1,5 GB
gotenbergKonwersja HTML do PDF (oparty na Chromium)~200 MB
frontendSerwuje UI + reverse proxy~20 MB

Łącznie: około 1,5 – 2,5 GB RAM.

Przydatne polecenia

# 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

Bezpieczeństwo sekretów

SekretCo chroniJeśli utracony
DB_PASSWORDDostęp do bazy danychOdzyskiwalny — reset przez narzędzia admin PostgreSQL
DB_ENCRYPTION_KEYKody MFA, hasło SMTP, klucz API FX, pola PIITrwale nieczytelny
TIMING_TOKEN_SECRETTokeny anty-timing-attackRegenerowalny — użytkownicy logują się ponownie
PUBLIC_LINK_PASSWORD_SESSION_SECRETSesje linków publicznychRegenerowalny — aktywne sesje wygasają

Krytyczny sekret to DB_ENCRYPTION_KEY. Przechowuj kopie .env poza tym serwerem. Szczegóły odzyskiwania: Rozwiązywanie problemów z instalacją.

Zalecane kolejne kroki

  • Skonfiguruj zaplanowane kopie zapasowe i przetestuj przywracanie.
  • Przetestuj generowanie PDF po pierwszym wdrożeniu.
  • Użyj publicznego serwera Ubuntu lub Coolify, gdy publiczne linki do ofert muszą działać dla klientów.

Last reviewed: Recently