Installation
Installer sur un serveur LAN Linux
Exécuter QuoteNode sur un serveur Linux interne pour un bureau ou une équipe VPN-only.
Installer sur un serveur LAN Linux
Utilisez ce chemin quand QuoteNode doit tourner sur un serveur Linux interne, VM, ou mini-PC accessible depuis le réseau de bureau ou le VPN.
Quand l’utiliser
- Plusieurs utilisateurs internes ont besoin d’une instance partagée stable.
- L’accès client public n’est pas requis.
- Vous préférez un hôte Linux plutôt que Docker Desktop.
Ce qui ne fonctionnera pas
- Les liens publics d’offre fonctionnent uniquement pour les utilisateurs qui peuvent atteindre l’adresse du serveur.
- La livraison d’email peut fonctionner avec SMTP, mais les destinataires hors du LAN ne peuvent pas ouvrir les liens internes.
- Un HTTPS interne auto-signé peut afficher des avertissements de navigateur sauf si votre organisation fait confiance à l’autorité de certification.
Prérequis
- Ubuntu, Debian, ou une autre distribution Linux maintenue.
- Docker Engine 24.0+ et Docker Compose v2.
- Une adresse IP statique ou une réservation DHCP pour le serveur.
- Accès SSH pour les opérateurs.
- Au moins 2 Go de RAM et 10 Go d’espace disque libre.
- Stockage de sauvegarde en dehors du volume Docker principal.
Vérifiez votre configuration :
docker --version # Should show 24.0+
docker compose version # Should show v2.x
Étape 1 — Créer un répertoire de projet
mkdir quotenode && cd quotenode
Étape 2 — Créer le fichier de configuration
Créez un fichier nommé .env. Remplacez 192.168.1.20 par l’IP LAN réelle de votre serveur ou le nom DNS interne (ex. crm.internal) :
# 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
# LAN URL — replace with your server IP or internal DNS name
CORS_ALLOWED_ORIGINS=http://192.168.1.20
DOMAIN=192.168.1.20
# 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
Si vous déployez derrière un reverse proxy interne avec HTTPS, utilisez plutôt l’origine HTTPS :
CORS_ALLOWED_ORIGINS=https://crm.internal.example
DOMAIN=crm.internal.example
Sauvegardez votre fichier
.envimmédiatement. Conservez une copie en dehors de ce serveur. Si vous perdezDB_ENCRYPTION_KEY, les champs chiffrés deviennent définitivement illisibles.
Étape 3 — Créer le fichier Docker Compose
Créez un fichier nommé 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:
Étape 4 — Démarrer QuoteNode
docker compose up -d
Docker téléchargera les images au premier lancement. Suivez le démarrage :
docker compose logs -f backend
Attendez de voir Started QuoteNodeApplication.
Étape 5 — Ouvrir QuoteNode
Naviguez vers http://192.168.1.20 (ou l’adresse de votre serveur) depuis n’importe quel appareil sur le LAN.
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.
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.
Commandes courantes
# 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
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 |
Le secret critique est
DB_ENCRYPTION_KEY. Stockez des sauvegardes de.enven dehors de ce serveur. Voir Résolution de problèmes d’installation pour les étapes de récupération.
Étapes suivantes recommandées
- Configurez des sauvegardes planifiées et testez une restauration.
- Testez la génération de PDF après le premier déploiement.
- Utilisez le Serveur public Ubuntu ou Coolify quand les liens publics doivent fonctionner pour les clients.