Installation
Installer sur un serveur public Ubuntu
Déployer QuoteNode sur un serveur Ubuntu public avec un domaine, HTTPS, SMTP, sauvegardes et bases de pare-feu.
Installer sur un serveur public Ubuntu
Utilisez ce chemin pour un déploiement en production accessible par les clients via un domaine public.
Quand l’utiliser
- Les clients externes doivent ouvrir les liens publics d’offre.
- Les messages email doivent contenir des liens fonctionnels.
- Vous voulez un contrôle direct du serveur plutôt qu’une couche PaaS.
Ce qui ne fonctionnera pas sans configuration correcte
- Les liens publics échouent si le DNS ne pointe pas vers le serveur.
- Les liens publics échouent si l’URL du navigateur diffère de la configuration CORS.
- L’émission du certificat HTTPS échoue si les ports 80/443 sont bloqués.
- Les liens email échouent si SMTP est manquant ou si les messages sont rejetés par le fournisseur mail du destinataire.
- Les déploiements avec IP domestique dynamique ont besoin de DDNS et de redirection de ports routeur ; un VPS est généralement plus simple.
Prérequis
- Serveur Ubuntu LTS ou VPS.
- Enregistrement DNS public, par exemple
crm.example.com, pointant vers le serveur. - Ports 80 et 443 ouverts depuis internet.
- Docker Engine 24.0+ et Docker Compose v2.
- Compte SMTP pour la livraison d’emails.
- Au moins 4 Go de RAM et 20 Go d’espace disque libre (recommandés en production).
- Destination de sauvegarde et une procédure de restauration.
Vérifiez Docker :
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 crm.example.com par votre vrai domaine :
# 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 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
Sauvegardez votre fichier
.envavant le premier usage en production. Conservez-le dans un gestionnaire de mots de passe ou un coffre-fort physique. LeDB_ENCRYPTION_KEYest critique — sa perte signifie que les données chiffrées sont perdues à jamais.
Alternative SMTP : Vous pouvez omettre les variables SMTP_* de .env et configurer l’email plus tard dans Paramètres > SMTP email dans QuoteNode. Le panneau admin stocke le mot de passe SMTP chiffré avec DB_ENCRYPTION_KEY, le tenant hors de votre fichier .env.
É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 — Configurer le pare-feu
Ouvrez uniquement ce qui est nécessaire :
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
N’exposez pas PostgreSQL publiquement. Il reste sur le réseau Docker.
Étape 5 — Démarrer QuoteNode
docker compose up -d
Suivez le démarrage :
docker compose logs -f backend
Attendez de voir Started QuoteNodeApplication. Le conteneur frontend (Caddy) obtiendra automatiquement un certificat Let’s Encrypt pour votre domaine.
Étape 6 — Ouvrir QuoteNode
Naviguez vers https://crm.example.com dans votre navigateur.
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.
Vérifications post-déploiement
- Se connecter et changer le mot de passe admin.
- Créer une offre de test.
- Générer un PDF.
- Créer et ouvrir un lien public depuis un autre appareil.
- Si SMTP est configuré, envoyer une notification de test et vérifier que les liens email fonctionnent.
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 (Caddy avec auto-HTTPS) | ~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
Checklist de mise à niveau
Avant chaque mise à niveau :
- Confirmer la version d’application courante dans la zone admin.
- Sauvegarder
.env. - Exécuter ou vérifier une sauvegarde fraîche de la base de données.
- Tirer les nouvelles images et redémarrer.
- Vérifier le health backend, la connexion, la génération PDF et un lien public d’offre.
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
.envdans un gestionnaire de mots de passe (1Password, Bitwarden). Pour une sécurité maximale, imprimez les secrets et conservez l’impression dans un coffre-fort physique. Ne commitez jamais.envdans le contrôle de version.
Récupération si .env est perdu
Si vous perdez votre fichier .env mais avez une sauvegarde de base de données non chiffrée (le mode par défaut) :
- Créez un nouveau
.envavec de nouveaux secrets. - Restaurez la base de données depuis votre sauvegarde.
- Toutes les données métier seront accessibles.
- Perdus : codes MFA (les utilisateurs se ré-inscrivent), mot de passe SMTP (à resaisir), clé API FX (à resaisir). Si
ENCRYPT_PII=trueétait activé, les données clients chiffrées sont également perdues.