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
.envimmédiatement. Si vous perdezDB_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 à jourCORS_ALLOWED_ORIGINSen 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 :
| Champ | Valeur |
|---|---|
[email protected] | |
| Mot de passe | Admin123! |
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ée | Pourquoi c’est important |
|---|---|
| PostgreSQL data | Base de données applicative principale |
| Uploads | Images produit, logos, pièces jointes |
| Generated PDFs | Fichiers d’offres et de documents |
| Backups | Archives de backup locales (si le worker de backup est activé) |
| GeoIP database | Données optionnelles de contrôle d’accès |
Qu’est-ce qui tourne ?
| Conteneur | Rôle | Utilisation RAM |
|---|---|---|
postgres | Stocke toutes vos données | ~256 Mo |
backend | Serveur API Java, logique métier | ~512 Mo – 1,5 Go |
gotenberg | Convertit HTML en PDF (basé sur Chromium) | ~200 Mo |
frontend | Sert l’interface web + reverse proxy | ~20 Mo |
Total : environ 1,5 – 2,5 Go de RAM.
Sécuriser vos secrets
| Secret | Ce qu’il protège | En cas de perte |
|---|---|---|
DB_PASSWORD | Accès à la base de données | Récupérable — réinitialiser via les outils admin PostgreSQL |
DB_ENCRYPTION_KEY | Codes MFA, mot de passe SMTP, clé API FX, champs PII | Définitivement illisible |
TIMING_TOKEN_SECRET | Tokens anti-timing-attack | Régénérer — les utilisateurs se ré-authentifient |
PUBLIC_LINK_PASSWORD_SESSION_SECRET | Sessions de liens publics | Régénérer — les sessions actives expirent |
Stockez des sauvegardes de
.enven dehors du NAS. Une défaillance NAS qui détruit votre seule copie deDB_ENCRYPTION_KEYrend 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.