Aller au contenu
Q
QuoteNode

Installation

Installer sur un ordinateur portable local

Exécuter QuoteNode localement pour évaluation sans l'exposer aux clients.

Installer sur un ordinateur portable local

Utilisez ce chemin quand vous voulez essayer QuoteNode sur un seul ordinateur. C’est le moyen le plus rapide d’évaluer l’application, mais ce n’est pas un déploiement destiné aux clients.

Quand l’utiliser

  • Vous voulez une instance de demo ou d’essai.
  • Vous testez la création d’offres, les PDFs, les modèles, les produits et les paramètres.
  • Vous n’avez pas besoin que les clients ouvrent les liens publics d’offre depuis un autre appareil.

Ce qui ne fonctionnera pas

  • Les liens publics d’offre générés en http://localhost/... fonctionnent uniquement sur le même ordinateur.
  • Les liens email ne sont généralement pas utiles car les destinataires ne peuvent pas ouvrir localhost depuis leur machine.
  • Le HTTPS n’est normalement pas configuré pour cette topologie.
  • L’ordinateur portable doit être allumé et Docker doit tourner.

Prérequis

  • Docker Desktop ou Docker Engine avec Docker Compose v2.
  • Au moins 2,5 Go de RAM disponibles pour la stack.
  • Au moins 10 Go d’espace disque libre.

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 avec les paramètres minimaux requis. Générez vos propres secrets — n’utilisez pas les valeurs de substitution en production :

# 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 — READ THIS BEFORE CONTINUING
# These values are UNIQUE to your installation.
# If you lose this file, you CANNOT regenerate the same secrets.
# 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

# Domain (for CORS and Caddy)
CORS_ALLOWED_ORIGINS=http://localhost
DOMAIN=localhost

# 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 .env immédiatement. Le DB_ENCRYPTION_KEY chiffre les données sensibles au repos. Si vous le perdez, les champs chiffrés (codes MFA, mot de passe SMTP, clés API) deviennent définitivement illisibles. Copiez ce fichier dans un endroit sécurisé.

Étape 3 — Créer le fichier Docker Compose

Créez un fichier nommé docker-compose.yml :

services:
  postgres:
    image: postgres:18-alpine
    cpus: 2.0
    mem_limit: 384m
    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: 384m
    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: 2.0
    mem_limit: 1280m
    depends_on:
      postgres: { condition: service_healthy }
      gotenberg: { condition: service_healthy }
    env_file: .env
    environment:
      SPRING_PROFILES_ACTIVE: prod
      # Single-container eval (WEB_MAINTENANCE backup profile): the backend runs
      # scheduled backups in-process, so no separate backup-worker container is needed.
      # For production, split into a web backend + a dedicated backup-only worker.
      JOBS_MODE: all
      BACKUP_RUNTIME_PROFILE: WEB_MAINTENANCE
      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: 1.0
    mem_limit: 128m
    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 de conteneurs (cela prend quelques minutes au premier lancement). Suivez la progression du démarrage :

docker compose logs -f backend

Attendez de voir Started QuoteNodeApplication — cela signifie que le backend est prêt.

Étape 5 — Ouvrir QuoteNode

Naviguez vers http://localhost dans votre navigateur.

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 (Paramètres > Mon profil > Changer le mot de passe).

Qu’est-ce qui tourne ?

Après docker compose up, vous avez 4 conteneurs :

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.

Commandes courantes

# Check if all services are running
docker compose ps

# View logs (all services)
docker compose logs -f

# View logs (backend only)
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

Votre fichier .env contient des secrets cryptographiques uniques à votre installation :

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, et tous les champs PII si ENCRYPT_PII=trueDéfinitivement illisible — impossible à déchiffrer sans la clé d’origine
TIMING_TOKEN_SECRETTokens anti-timing-attackRégénérer — tokens existants invalides, les utilisateurs se ré-authentifient
PUBLIC_LINK_PASSWORD_SESSION_SECRETSessions de liens publicsRégénérer — sessions actives expirent, les liens fonctionnent toujours

Le secret critique est DB_ENCRYPTION_KEY. Tous les autres secrets peuvent être régénérés avec un inconvénient mineur. Mais DB_ENCRYPTION_KEY chiffre les données au repos — sa perte signifie que ces champs sont perdus à jamais.

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 de sauvegarde par défaut) :

  1. Créez un nouveau .env avec de nouveaux secrets.
  2. Restaurez la base de données depuis votre sauvegarde.
  3. Toutes les données métier (clients, offres, produits, utilisateurs) seront pleinement accessibles.
  4. Seuls quelques champs sont perdus : codes MFA (les utilisateurs se ré-inscrivent), mot de passe SMTP (à resaisir dans les paramètres), clé API FX (à resaisir dans les paramètres). Si ENCRYPT_PII=true était activé, les données clients chiffrées sont également perdues.

Sauvegardes

Cette configuration à conteneur unique exécute les sauvegardes planifiées dans le processus du backend (JOBS_MODE: all), vous n’avez donc pas besoin d’un conteneur backup-worker séparé. La sauvegarde elle-même s’exécute comme un pipeline shell (pg_dump → compression → chiffrement) en dehors de la JVM, son coût mémoire est donc faible — c’est pourquoi le backend sur portable est dimensionné à 1280m plutôt qu’à 1g.

C’est acceptable pour un portable ou une instance d’évaluation. Pour un déploiement en production, exécutez un conteneur worker dédié backup-only (JOBS_MODE: backup-only) à côté d’un backend web (JOBS_MODE: web) afin que les sauvegardes n’entrent jamais en concurrence avec le trafic web pour la mémoire. Voir Sauvegarde et restauration.

Passer du portable au serveur

Ne publiez pas de liens depuis votre portable vers des clients. Quand vous êtes prêt pour un déploiement partagé ou public, choisissez l’un de ces chemins :

Last reviewed: Recently