Przejdź do treści
Q
QuoteNode

Instalacja

Instalacja za pomocą Portainer, QNAP lub NAS

Wdrożenie QuoteNode na NAS lub hoście Docker zarządzanym przez Portainer z pełnymi instrukcjami konfiguracji.

Instalacja za pomocą Portainer, QNAP lub NAS

Użyj tej ścieżki, jeśli korzystasz z Docker przez Portainer, QNAP Container Station, Synology lub podobną platformę. Dokładny interfejs użytkownika różni się w zależności od dostawcy, ale podstawowy stos Docker Compose jest identyczny.

Kiedy to zastosować

  • Już zarządzasz stosami Docker za pośrednictwem interfejsu do zarządzania kontenerami.
  • Rozumiesz, jak platforma mapuje woluminy i porty.
  • Potrafisz weryfikować kopie zapasowe poza interfejsem NAS.

Co może nie działać

  • Publiczne linki nie działają poza siecią LAN, chyba że skonfigurowano NAT, DNS, proxy i HTTPS.
  • Tryby uśpienia NAS mogą przerywać działanie usługi.
  • Niektóre interfejsy Docker w NAS modyfikują pliki compose lub zmienne środowiskowe; zweryfikuj wyrenderowany stos przed poleganiem na nim.
  • Kopie zapasowe przechowywane wyłącznie na tym samym NAS nie chronią przed awarią NAS.

Wymagania wstępne

  • Obsługa Docker Compose v2 na Twojej platformie.
  • Obsługa woluminów trwałych dla danych PostgreSQL, przesłanych plików, PDF-ów i kopii zapasowych.
  • Co najmniej 2 GB RAM dostępnego i 10 GB wolnego miejsca na dysku.
  • Stabilny adres URL: adres IP sieci LAN do użytku wewnętrznego lub publiczna domena za reverse proxy dla linków klientów.

Krok 1 — Utwórz plik konfiguracyjny

Utwórz plik .env (lub ustaw zmienne przez interfejs środowiskowy platformy). Zastąp adres URL rzeczywistym adresem NAS lub publiczną domeną:

W przypadku wdrożenia tylko wewnętrznego NAS:

# 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

# 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

W przypadku publicznej domeny za reverse proxy:

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

Zapisz plik .env natychmiast. Jeśli utracisz DB_ENCRYPTION_KEY, zaszyfrowane pola staną się trwale nieczytelne.

Krok 2 — Utwórz stos Docker Compose

Użyj edytora stosów w Portainer lub interfejsie Docker NAS, albo 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:

Konflikty portów: Jeśli Twój NAS już używa portu 80 lub 443, zmień lewą stronę mapowania ports (np. "8080:80") i odpowiednio zaktualizuj CORS_ALLOWED_ORIGINS (np. http://nas.local:8080).

Krok 3 — Wdróż i zweryfikuj

Uruchom stos przez interfejs platformy lub przez SSH:

docker compose up -d
docker compose logs -f backend

Poczekaj, aż zobaczysz Started QuoteNodeApplication.

Krok 4 — Otwórz QuoteNode

Przejdź do adresu URL Twojego NAS (np. http://nas.local lub https://crm.example.com).

Domyślne dane logowania:

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

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

Lista kontrolna trwałości danych

Sprawdź, czy poniższe dane są mapowane na woluminy trwałe (nie na tymczasowy storage kontenera):

DaneDlaczego to ważne
PostgreSQL dataGłówna baza danych aplikacji
UploadsZdjęcia produktów, loga, załączniki
Generated PDFsPliki ofert i dokumentów
BackupsLokalne archiwa kopii zapasowych (jeśli worker kopii zapasowych jest włączony)
GeoIP databaseOpcjonalne dane kontroli dostępu

Co działa w tle?

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

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

Bezpieczeństwo sekretów

SekretCo chroniW przypadku utraty
DB_PASSWORDDostęp do bazy danychMożliwy do odzyskania — zresetuj przez narzędzia admin PostgreSQL
DB_ENCRYPTION_KEYKody MFA, hasło SMTP, klucz FX API, pola PIITrwale nieczytelne
TIMING_TOKEN_SECRETTokeny anty-timing-attackZregeneruj — użytkownicy ponownie się uwierzytelniają
PUBLIC_LINK_PASSWORD_SESSION_SECRETSesje publicznych linkówZregeneruj — aktywne sesje wygasają

Przechowuj kopie zapasowe .env poza NAS. Awaria NAS niszcząca jedyną kopię DB_ENCRYPTION_KEY powoduje trwałą utratę zaszyfrowanych danych.

Zalecane kolejne kroki

  • Skonfiguruj kopie zapasowe w lokalizacji poza NAS.
  • Przetestuj generowanie PDF po pierwszym wdrożeniu.
  • Jeśli chcesz płynniejszą ścieżkę wdrożenia publicznego, rozważ Coolify na VPS.

Last reviewed: Recently