Vai al contenuto
Q
QuoteNode

Installation

Installare su un server pubblico Ubuntu

Distribuisci QuoteNode su un server Ubuntu pubblico con dominio, HTTPS, SMTP, backup e firewall di base.

Installare su un server pubblico Ubuntu

Usa questo percorso per un deployment in produzione raggiungibile dai clienti tramite un dominio pubblico.

Quando usarlo

  • I clienti esterni devono aprire i link pubblici delle offerte.
  • I messaggi email dovrebbero contenere link funzionanti.
  • Vuoi il controllo diretto sul server invece di un layer PaaS.

Cosa non funzionerà senza la corretta configurazione

  • I link pubblici falliscono se il DNS non punta al server.
  • I link pubblici falliscono se l’URL del browser differisce dalla configurazione CORS.
  • L’emissione del certificato HTTPS fallisce se le porte 80/443 sono bloccate.
  • I link email falliscono se SMTP manca o se i messaggi sono rifiutati dal provider di posta del destinatario.
  • I deployment con IP domestico dinamico necessitano DDNS e port forwarding del router; un VPS è solitamente più semplice.

Prerequisiti

  • Server Ubuntu LTS o VPS.
  • Record DNS pubblico, ad esempio crm.example.com, che punta al server.
  • Porte 80 e 443 aperte da internet.
  • Docker Engine 24.0+ e Docker Compose v2.
  • Account SMTP per la consegna email.
  • Almeno 4 GB di RAM e 20 GB di spazio libero su disco (raccomandati per la produzione).
  • Destinazione backup e una procedura di restore.

Controlla Docker:

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

Passo 1 — Creare una directory di progetto

mkdir quotenode && cd quotenode

Passo 2 — Creare il file di configurazione

Crea un file chiamato .env. Sostituisci crm.example.com con il tuo dominio reale:

# 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

# L'IP del client viene rilevato automaticamente dietro proxy interni e CDN (incluso Cloudflare) — lascia vuoto.
# Imposta solo per un proxy insolito il cui peer di trasporto è un indirizzo PUBBLICO da considerare attendibile (IP/CIDR o hostname).
SECURITY_TRUSTED_PROXIES=

# Application
LOG_LEVEL=INFO
SPRING_PROFILES_ACTIVE=prod

Esegui il backup del tuo file .env prima del primo uso in produzione. Conservalo in un password manager o in una cassaforte fisica. Il DB_ENCRYPTION_KEY è critico — perderlo significa che i dati cifrati sono persi per sempre.

Alternativa SMTP: Puoi omettere le variabili SMTP_* da .env e configurare l’email in seguito in Impostazioni > SMTP email dentro QuoteNode. Il pannello admin conserva la password SMTP cifrata con DB_ENCRYPTION_KEY, mantenendola fuori dal file .env.

Passo 3 — Creare il file Docker Compose

Crea un file chiamato 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:

Passo 4 — Configurare il firewall

Apri solo ciò che serve:

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

Non esporre PostgreSQL pubblicamente. Resta sulla rete Docker.

Passo 5 — Avviare QuoteNode

docker compose up -d

Monitora l’avvio:

docker compose logs -f backend

Attendi di vedere Started QuoteNodeApplication. Il container frontend (Caddy) otterrà automaticamente un certificato Let’s Encrypt per il tuo dominio.

Passo 6 — Aprire QuoteNode

Naviga su https://crm.example.com nel tuo browser.

Credenziali di accesso predefinite:

CampoValore
Email[email protected]
PasswordAdmin123!

Cambia la password predefinita immediatamente dopo aver effettuato l’accesso.

Verifiche post-deployment

  1. Accedere e cambiare la password admin.
  2. Creare un’offerta di test.
  3. Generare un PDF.
  4. Creare e aprire un link pubblico da un altro dispositivo.
  5. Se SMTP è configurato, inviare una notifica di test e verificare che i link email funzionino.

Cosa è in esecuzione?

ContainerCosa faUtilizzo RAM
postgresArchivia tutti i tuoi dati~256 MB
backendServer API Java, logica di business~512 MB – 1,5 GB
gotenbergConverte HTML in PDF (basato su Chromium)~200 MB
frontendServe l’interfaccia web + reverse proxy (Caddy con auto-HTTPS)~20 MB

Totale: circa 1,5 – 2,5 GB di RAM.

Comandi comuni

# 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

Checklist di aggiornamento

Prima di ogni aggiornamento:

  1. Conferma la versione app attuale nell’area admin.
  2. Esegui il backup di .env.
  3. Esegui o verifica un backup fresco del database.
  4. Esegui il pull delle nuove immagini e riavvia.
  5. Controlla health backend, login, generazione PDF e un link offerta pubblico.

Mantenere al sicuro i tuoi segreti

SegretoCosa proteggeSe perso
DB_PASSWORDAccesso al databaseRecuperabile — reimposta tramite strumenti di amministrazione PostgreSQL
DB_ENCRYPTION_KEYCodici MFA, password SMTP, chiave API FX, campi PIIPermanentemente illeggibile
TIMING_TOKEN_SECRETToken anti-timing-attackRigenera — gli utenti si ri-autenticano
PUBLIC_LINK_PASSWORD_SESSION_SECRETSessioni dei link pubbliciRigenera — le sessioni attive scadono

Conserva .env in un password manager (1Password, Bitwarden). Per massima sicurezza, stampa i segreti e conserva la stampa in una cassaforte fisica. Non committare mai .env nel controllo versione.

Ripristino se .env è perso

Se perdi il tuo file .env ma hai un backup del database non cifrato (il modo predefinito):

  1. Crea un nuovo .env con nuovi segreti.
  2. Ripristina il database dal tuo backup.
  3. Tutti i dati di business saranno accessibili.
  4. Persi: codici MFA (gli utenti si re-iscrivono), password SMTP (reinserire), chiave API FX (reinserire). Se ENCRYPT_PII=true era abilitato, anche i dati cliente cifrati vengono persi.

Last reviewed: Recently