Installation
Installare con Portainer, QNAP o NAS
Distribuisci QuoteNode su un NAS o su un host Docker gestito da Portainer con istruzioni di configurazione complete.
Installare con Portainer, QNAP o NAS
Usa questo percorso se esegui Docker tramite Portainer, QNAP Container Station, Synology o una piattaforma simile. L’interfaccia esatta differisce in base al vendor, ma lo stack Docker Compose sottostante è identico.
Quando usarlo
- Gestisci già stack Docker tramite un’interfaccia di gestione dei container.
- Capisci come la piattaforma mappa volumi e porte.
- Puoi verificare i backup al di fuori dell’interfaccia NAS.
Cosa potrebbe non funzionare
- I link pubblici non funzionano al di fuori della LAN a meno che NAT, DNS, proxy e HTTPS non siano configurati.
- Le modalità di sospensione del NAS possono interrompere il servizio.
- Alcune interfacce Docker dei NAS riscrivono file compose o variabili d’ambiente; verifica lo stack renderizzato prima di farvi affidamento.
- I backup archiviati solo sullo stesso NAS non proteggono contro i guasti del NAS.
Prerequisiti
- Supporto Docker Compose v2 nella tua piattaforma.
- Supporto di volumi persistenti per dati PostgreSQL, upload, PDF e backup.
- Almeno 2 GB di RAM disponibili e 10 GB di spazio libero su disco.
- Un URL stabile: IP LAN per uso interno, o dominio pubblico dietro un reverse proxy per i link dei clienti.
Passo 1 — Creare il file di configurazione
Crea un file .env (o imposta le variabili tramite l’interfaccia ambiente della tua piattaforma). Sostituisci l’URL con il tuo indirizzo NAS reale o dominio pubblico:
Per un deployment solo NAS interno:
# 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
# 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
Per un dominio pubblico dietro un reverse proxy:
CORS_ALLOWED_ORIGINS=https://crm.example.com
DOMAIN=crm.example.com
Salva il tuo
.envimmediatamente. Se perdiDB_ENCRYPTION_KEY, i campi cifrati diventano permanentemente illeggibili.
Passo 2 — Creare lo stack Docker Compose
Usa l’editor di stack in Portainer o nell’interfaccia Docker del tuo NAS, oppure crea un file 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:
Conflitti di porte: Se il tuo NAS usa già la porta 80 o 443, cambia il lato sinistro del mapping
ports(es."8080:80") e aggiornaCORS_ALLOWED_ORIGINSdi conseguenza (es.http://nas.local:8080).
Passo 3 — Distribuire e verificare
Avvia lo stack tramite l’interfaccia della piattaforma o via SSH:
docker compose up -d
docker compose logs -f backend
Attendi di vedere Started QuoteNodeApplication.
Passo 4 — Aprire QuoteNode
Naviga al tuo URL NAS (es. http://nas.local o https://crm.example.com).
Credenziali di accesso predefinite:
| Campo | Valore |
|---|---|
[email protected] | |
| Password | Admin123! |
Cambia la password predefinita immediatamente dopo aver effettuato l’accesso.
Checklist di persistenza
Verifica che questi elementi siano mappati su volumi persistenti (non su storage effimero del container):
| Dato | Perché conta |
|---|---|
| PostgreSQL data | Database applicativo principale |
| Uploads | Immagini prodotto, logo, allegati |
| Generated PDFs | File di offerta e documenti |
| Backups | Archivi di backup locali (se il worker di backup è abilitato) |
| GeoIP database | Dati opzionali di controllo accessi |
Cosa è in esecuzione?
| Container | Cosa fa | Utilizzo RAM |
|---|---|---|
postgres | Archivia tutti i tuoi dati | ~256 MB |
backend | Server API Java, logica di business | ~512 MB – 1,5 GB |
gotenberg | Converte HTML in PDF (basato su Chromium) | ~200 MB |
frontend | Serve l’interfaccia web + reverse proxy | ~20 MB |
Totale: circa 1,5 – 2,5 GB di RAM.
Mantenere al sicuro i tuoi segreti
| Segreto | Cosa protegge | Se perso |
|---|---|---|
DB_PASSWORD | Accesso al database | Recuperabile — reimposta tramite strumenti di amministrazione PostgreSQL |
DB_ENCRYPTION_KEY | Codici MFA, password SMTP, chiave API FX, campi PII | Permanentemente illeggibile |
TIMING_TOKEN_SECRET | Token anti-timing-attack | Rigenera — gli utenti si ri-autenticano |
PUBLIC_LINK_PASSWORD_SESSION_SECRET | Sessioni dei link pubblici | Rigenera — le sessioni attive scadono |
Conserva backup di
.enval di fuori del NAS. Un guasto del NAS che distrugge la tua unica copia diDB_ENCRYPTION_KEYrende i dati cifrati irrecuperabili.
Passi successivi consigliati
- Configura backup in una posizione esterna al NAS.
- Testa la generazione PDF dopo il primo deployment.
- Se vuoi un percorso di deployment pubblico più agevole, considera Coolify su un VPS.