Aller au contenu
Q
QuoteNode

Installation

Installer avec Portainer, QNAP ou NAS

Déployer QuoteNode sur un NAS ou un hôte Docker géré par Portainer avec des instructions d'installation complètes.

Installer avec Portainer, QNAP ou NAS

Utilisez ce chemin si vous exécutez Docker via Portainer, QNAP Container Station, Synology ou une plateforme similaire. L’interface exacte diffère selon le vendeur, mais le stack Docker Compose sous-jacent est identique.

Quand l’utiliser

  • Vous opérez déjà des stacks Docker via une interface de gestion de conteneurs.
  • Vous comprenez comment la plateforme mappe les volumes et les ports.
  • Vous pouvez vérifier les sauvegardes en dehors de l’interface NAS.

Ce qui peut ne pas fonctionner

  • Les liens publics ne fonctionnent pas hors LAN sauf si NAT, DNS, proxy et HTTPS sont configurés.
  • Les modes veille du NAS peuvent interrompre le service.
  • Certaines interfaces Docker NAS réécrivent les fichiers compose ou les variables d’environnement ; vérifiez la stack rendue avant de vous y fier.
  • Les sauvegardes stockées uniquement sur le même NAS ne protègent pas contre une défaillance NAS.

Prérequis

  • Support Docker Compose v2 sur votre plateforme.
  • Support de volumes persistants pour les données PostgreSQL, les uploads, les PDFs et les sauvegardes.
  • Au moins 2 Go de RAM disponibles et 10 Go d’espace disque libre.
  • Une URL stable : IP LAN pour usage interne, ou domaine public derrière un reverse proxy pour les liens clients.

Étape 1 — Créer le fichier de configuration

Créez un fichier .env (ou définissez des variables via l’interface environnement de votre plateforme). Remplacez l’URL par votre adresse NAS réelle ou domaine public :

Pour un déploiement NAS interne uniquement :

# 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 du client est détectée automatiquement derrière des proxys internes et des CDN (Cloudflare inclus) — laisser vide.
# À définir uniquement pour un proxy inhabituel dont le pair de transport est une adresse PUBLIQUE à approuver (IP/CIDR ou nom d'hôte).
SECURITY_TRUSTED_PROXIES=

# Application
LOG_LEVEL=INFO
SPRING_PROFILES_ACTIVE=prod

Pour un domaine public derrière un reverse proxy :

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

Sauvegardez votre .env immédiatement. Si vous perdez DB_ENCRYPTION_KEY, les champs chiffrés deviennent définitivement illisibles.

Étape 2 — Créer le stack Docker Compose

Utilisez l’éditeur de stack dans Portainer ou votre interface NAS Docker, ou créez un fichier 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:

Conflits de ports : Si votre NAS utilise déjà le port 80 ou 443, modifiez le côté gauche du mapping ports (ex. "8080:80") et mettez à jour CORS_ALLOWED_ORIGINS en conséquence (ex. http://nas.local:8080).

Étape 3 — Déployer et vérifier

Démarrez le stack via votre interface plateforme ou via SSH :

docker compose up -d
docker compose logs -f backend

Attendez de voir Started QuoteNodeApplication.

Étape 4 — Ouvrir QuoteNode

Naviguez vers votre URL NAS (ex. http://nas.local ou https://crm.example.com).

Identifiants de connexion par défaut :

ChampValeur
Email[email protected]
Mot de passeAdmin123!

Changez le mot de passe par défaut immédiatement après la connexion.

Checklist de persistance

Vérifiez que ces éléments sont mappés sur des volumes persistants (pas sur un stockage éphémère du conteneur) :

DonnéePourquoi c’est important
PostgreSQL dataBase de données applicative principale
UploadsImages produit, logos, pièces jointes
Generated PDFsFichiers d’offres et de documents
BackupsArchives de backup locales (si le worker de backup est activé)
GeoIP databaseDonnées optionnelles de contrôle d’accès

Qu’est-ce qui tourne ?

ConteneurRôleUtilisation RAM
postgresStocke toutes vos données~256 Mo
backendServeur API Java, logique métier~512 Mo – 1,5 Go
gotenbergConvertit HTML en PDF (basé sur Chromium)~200 Mo
frontendSert l’interface web + reverse proxy~20 Mo

Total : environ 1,5 – 2,5 Go de RAM.

Sécuriser vos secrets

SecretCe qu’il protègeEn cas de perte
DB_PASSWORDAccès à la base de donnéesRécupérable — réinitialiser via les outils admin PostgreSQL
DB_ENCRYPTION_KEYCodes MFA, mot de passe SMTP, clé API FX, champs PIIDéfinitivement illisible
TIMING_TOKEN_SECRETTokens anti-timing-attackRégénérer — les utilisateurs se ré-authentifient
PUBLIC_LINK_PASSWORD_SESSION_SECRETSessions de liens publicsRégénérer — les sessions actives expirent

Stockez des sauvegardes de .env en dehors du NAS. Une défaillance NAS qui détruit votre seule copie de DB_ENCRYPTION_KEY rend les données chiffrées irrécupérables.

Étapes suivantes recommandées

  • Configurez des sauvegardes dans un emplacement en dehors du NAS.
  • Testez la génération de PDF après le premier déploiement.
  • Si vous voulez un chemin de déploiement public plus fluide, envisagez Coolify sur un VPS.

Last reviewed: Recently