Aller au contenu
Q
QuoteNode

Installation

Mettre à jour QuoteNode

Vérifier les nouvelles versions, passer au paquet d’une nouvelle version et revenir en arrière en toute sécurité.

Mettre à jour QuoteNode

QuoteNode vérifie automatiquement la disponibilité de nouvelles versions. Lorsqu’une version plus récente existe, le panneau d’administration affiche une notification avec le libellé de la version et un lien vers les notes de version.

Chaque version est publiée sous forme de paquet de déploiement : docker-compose.yml (et docker-compose.coolify.yml) avec les images de la version épinglées par digest, env.example, release.json et les outils de operator/. Mettre à jour consiste à remplacer le fichier Compose par celui du paquet suivant. La version actuelle est v0.9.8-alpha (paquet).

La procédure dépend du mode d’installation. La liste de contrôle et les commandes ci-dessous concernent un répertoire d’installation (serveur, LAN, portable ou dossier sur un NAS avec docker-compose.yml et .env). Une stack Portainer n’a pas de tel répertoire : passez à Stack Portainer. Coolify : passez à Coolify.

Problème connu dans v0.9.5-alpha : destination de sauvegarde d’exemple

Le env.example de v0.9.5-alpha contient une ligne d’exemple active, BACKUP_RCLONE_REMOTE=s3:mybucket/backups. Cette destination n’est pas configurée : si la ligne arrive dans vos réglages, chaque sauvegarde échoue, et un envoi échoué ne laisse aucune copie locale de cette sauvegarde. Les réglages de ces guides ne la contiennent jamais ; vérifiez votre installation si vous avez créé .env à partir de env.example ou y avez ajouté des réglages de ce fichier lors d’une mise à jour.

Dans un répertoire d’installation, commentez exactement cette ligne d’exemple (une vraie destination reste inchangée) et recréez les conteneurs :

# Run in Bash (for example Linux, Git Bash or WSL); other shells can edit the exact placeholder manually.
(
  set -eu
  umask 077
  temporary_env="$(mktemp .env.backup-remote.XXXXXX)"
  trap 'rm -f "$temporary_env"' EXIT
  carriage_return="$(printf '\r')"
  # Match only the published placeholder, with either LF or Windows CRLF line endings.
  sample_pattern="^BACKUP_RCLONE_REMOTE=s3:mybucket/backups${carriage_return}\{0,1\}$"
  sed "s|${sample_pattern}|# &|" .env > "$temporary_env"
  if LC_ALL=C grep -Eq "^BACKUP_RCLONE_REMOTE=s3:mybucket/backups${carriage_return}?$" "$temporary_env"; then
    echo "Sample backup remote is still active; settings were not replaced." >&2
    exit 1
  else
    match_status=$?
    [ "$match_status" -eq 1 ] || exit "$match_status"
  fi
  # Keep real remote settings unchanged; publish a changed file atomically with private permissions.
  if ! cmp -s .env "$temporary_env"; then
    mv "$temporary_env" .env
  fi
  docker compose up -d
)

Dans Portainer, supprimez la variable de stack BACKUP_RCLONE_REMOTE si elle a cette valeur d’exemple, puis mettez la stack à jour. La définition Coolify de v0.9.5-alpha ne transmet pas cette variable à l’application ; supprimez la valeur d’exemple de la ressource avant de passer à une version ultérieure.

Les sauvegardes restent alors dans le volume de sauvegardes. Lancez une sauvegarde dans le panneau d’administration (Admin → Security → Backup), vérifiez qu’elle se termine avec succès et prévoyez une copie hors du serveur : une destination rclone configurée ou des copies régulières des archives sur une autre machine (Sauvegarde et restauration).

Passer à PostgreSQL 18

Les fichiers Compose utilisent déjà postgres:18-alpine : les nouvelles installations n’ont rien à faire. Si une version alpha antérieure fonctionnait sous PostgreSQL 16, migrez les données une fois — un serveur PostgreSQL 18 ne démarre pas sur un répertoire de données plus ancien, et l’application ne le réécrit jamais automatiquement. Suivez la procédure dédiée et sûre : Migrer les données vers PostgreSQL 18 (en ligne de commande ou uniquement par interface, selon la plateforme).

Fonctionnement de la vérification de version

L’interface d’administration récupère https://quotenode.dev/releases/latest.json à la connexion d’un administrateur. Il s’agit d’une requête GET en lecture seule, sans authentification ; aucune donnée de votre instance n’est envoyée. Si le manifeste est inaccessible, la vérification échoue silencieusement et le panneau fonctionne normalement.

La vérification et l’URL du manifeste font partie de l’interface web déjà construite. Définir VITE_RELEASE_CHECK_ENABLED ou VITE_RELEASE_MANIFEST_URL dans .env ou dans Coolify n’a aucun effet sur une version ; ces valeurs ne s’appliquent que si vous construisez vous-même l’image du frontend à partir des sources. Pour qu’une installation ne contacte pas quotenode.dev, bloquez cette adresse dans votre réseau.

Liste de contrôle avant la mise à jour

Pour un répertoire d’installation ; Portainer et Coolify ont leurs propres sections ci-dessous.

  1. Notez la version actuelle : release.json dans le répertoire d’installation, ou Admin > Licence.
  2. Copiez .env hors du serveur — il contient des secrets impossibles à régénérer (en particulier DB_ENCRYPTION_KEY).
  3. Téléchargez le nouveau paquet à côté de l’installation. Cela ne modifie rien de ce qui tourne :
mkdir -p ../next && cd ../next
curl -fsSLO https://quotenode.dev/releases/v0.9.8-alpha/quotenode-deploy-v0.9.8-alpha.tar.gz
tar -xzf quotenode-deploy-v0.9.8-alpha.tar.gz --strip-components=1
cd -
# Paramètres ajoutés ou supprimés par la nouvelle version ? Comparez votre .env au nouveau modèle.
diff <(grep -o '^[A-Z_]*=' .env | sort) <(grep -o '^[A-Z_]*=' ../next/env.example | sort)
  1. Ajoutez à .env les paramètres dont la nouvelle version a besoin (la comparaison ci-dessus les liste ; installations antérieures aux paquets de version : voir Installations antérieures aux paquets de version). L’installation en cours ne les utilise pas encore.
  2. Créez le point de contrôle de mise à jour et une sauvegarde vérifiée avec l’outil du nouveau paquet. Cela ne modifie rien de ce qui tourne et s’arrête à la première erreur :
BACKUP_ARCHIVE_ENCRYPTION_MODE=AGE_RECIPIENT BACKUP_AGE_RECIPIENT=age1... \
  ../next/operator/upgrade.sh prepare --export-to ../quotenode-backups

Le point de contrôle (dans .quotenode-upgrade/, utilisé uniquement par cette installation) enregistre les docker-compose.yml, .env et release.json installés, l’identité des images en cours d’exécution et l’état du schéma de la base. La sauvegarde est faite avec les outils de la nouvelle version sur le projet Compose et les volumes de cette installation, reste locale pour cette exécution même si des sauvegardes distantes sont configurées, et n’est conservée dans ../quotenode-backups qu’une fois son SHA-256 vérifié. Copiez ce répertoire hors du serveur avant de continuer. Le destinataire age vient de votre Recovery Kit (Sauvegarde et restauration).

  1. Si les sauvegardes planifiées sont activées, vérifiez aussi que la dernière a réussi (panneau d’administration).

Procédure de mise à jour

Docker Compose (serveur, LAN, portable, dossier NAS)

Après la liste de contrôle, exécutez dans le répertoire d’installation, afin que le projet Compose et ses volumes restent les mêmes :

../next/operator/upgrade.sh apply

upgrade.sh apply télécharge d’abord toutes les images de la nouvelle version et s’arrête à la première erreur : si un téléchargement échoue, l’installation continue de tourner sans changement. Ensuite seulement, il installe docker-compose.yml, release.json, env.example et operator/ du paquet, démarre la nouvelle version et attend qu’elle soit saine. Les migrations de la base s’exécutent automatiquement au démarrage du nouveau backend. Docker Compose 2.17 ou plus récent est requis.

Stack Portainer

upgrade.sh a besoin d’un répertoire d’installation ; une stack Portainer se met donc à jour dans Portainer :

  1. Vérifiez que la dernière sauvegarde planifiée a réussi (panneau d’administration), sauvegardez les volumes de la stack avec l’outil d’instantané ou de sauvegarde de votre plateforme et enregistrez une copie de la définition actuelle de la stack et de ses variables d’environnement.
  2. Ouvrez l’Editor de la stack et remplacez la définition par le bloc ci-dessous : l’adaptation Portainer du docker-compose.yml de la version, le même bloc que dans Installer avec Portainer. Ne collez pas le fichier d’origine du paquet : il lit .env, que Portainer n’a pas.
  3. Conservez le nom de la stack et ses variables d’environnement (stack.env) ; ajoutez les réglages dont la nouvelle version a besoin (comparez avec son env.example).
  4. Cliquez sur Update the stack avec le téléchargement des images activé. Les migrations de la base de données s’exécutent au démarrage du nouveau backend.
# Portainer Web editor adaptation of the release docker-compose.yml: env_file reads stack.env (the stack's
# environment variables) instead of .env in postgres, backend and backup-worker. Images, services, ports and
# volumes are unchanged. For a folder-based installation use the unchanged file of the release package.
x-json-file-logging: &json-file-logging
  driver: json-file
  options:
    max-size: "${DOCKER_LOG_MAX_SIZE:-10m}"
    max-file: "${DOCKER_LOG_MAX_FILE:-5}"

# ==========================================================================
# QuoteNode — standalone deployment (docker compose)
# GENERATED by scripts/render-deployment.mjs — do not edit by hand.
# Release v0.9.8-alpha (commit ff74453ca68f3c40bd86a32f0b0b813aaffc7aea, build 28); platforms: linux/amd64.
# API image:      ghcr.io/lesisty7/quotenode/quotenode-api@sha256:0ed701f952c27ea0e1db168a00de75facb231f7c6d5f6b4f0f3b77ef98d4f140
# Frontend image: ghcr.io/lesisty7/quotenode/quotenode-frontend@sha256:40a1cdc4fca5cebd9f43d34daef4ba059a88000ff08af821e199566f07260606
#
# Settings: the .env file in this directory (start from env.example, the commented catalogue of every
# setting; postgres, backend and backup-worker read it). Start: docker compose up -d
# DOMAIN: public host name for automatic HTTPS, or :80 / http://<address> for plain HTTP on a trusted LAN.
# Only the caddy entry point publishes ports (HTTP_PORT/HTTPS_PORT, default 80/443).
# Upgrades: replace this file with the next release package version; volumes keep the data.
# ==========================================================================

services:
  postgres:
    # Database (PostgreSQL 18); internal network only, data in the database volume.
    image: postgres:18-alpine@sha256:77f585114c32fbca283dc835b0596f4e52b51b4c6662d7810b2f4084f60a1873
    # JIT is off by default: for this OLTP workload most queries fall below jit_above_cost,
    # so JIT compilation rarely helps and can add latency. Set PG_JIT=on to re-enable.
    command: ["postgres", "-c", "jit=${PG_JIT:-off}"]
    env_file: stack.env
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_INITDB_ARGS: "--data-checksums"
      # postgres:18 refuses to start on a bare /var/lib/postgresql/data mount (new default layout).
      # Pin PGDATA to the legacy path so the existing volume mount keeps working; major upgrades go
      # through a logical dump/restore, never an in-place upgrade of the data directory.
      PGDATA: /var/lib/postgresql/data
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d ${DB_NAME}"]
      interval: 10s
      timeout: 5s
      retries: 10
    # CPU ceilings are opt-in (*_CPUS): 0 = no ceiling, all host cores. Docker refuses a ceiling above the
    # host's core count, so a fixed default would stop the stack on smaller hosts (minimum: 2 cores).
    cpus: ${POSTGRES_CPUS:-0}
    # Ceiling, not a reservation: PG sits at tens of MB until working set/connections grow.
    # Default 512m fits the 4 GB-VM profile; raise POSTGRES_MEM_LIMIT for larger tiers.
    mem_limit: ${POSTGRES_MEM_LIMIT:-512m}
    restart: unless-stopped
    logging: *json-file-logging
    # No published host port: the database is reachable only on the internal network.

  gotenberg:
    # PDF rendering (Chromium) for the backend; internal network only, keeps no data.
    image: gotenberg/gotenberg:8@sha256:aa552cc115db488e0f0bcb07446aac13071ad51505b642c84bb894500907b42b
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:3000/health"]
      interval: 10s
      timeout: 5s
      retries: 5
    cpus: ${GOTENBERG_CPUS:-0}
    # Chromium PDF rendering: measured ~188 MiB peak rendering a real offer template, so
    # 448m keeps ~2.4x headroom. Freed budget goes to backup-worker (closer to its limit).
    mem_limit: ${GOTENBERG_MEM_LIMIT:-448m}
    restart: unless-stopped
    logging: *json-file-logging

  backend:
    # API server (Java): business logic and web jobs; uploads, PDFs and the GeoIP database live in volumes.
    image: ghcr.io/lesisty7/quotenode/quotenode-api@sha256:0ed701f952c27ea0e1db168a00de75facb231f7c6d5f6b4f0f3b77ef98d4f140
    # Time Docker gives the backend between SIGTERM and SIGKILL. 60 s = the SMTP handoff hard limit
    # (mail.handoff.deadline-ms + end-of-data-allowance-ms = 25 s) + 5 s to record its outcome + the HTTP
    # graceful drain phase (30 s). A ceiling, not a delay: an idle backend exits in seconds.
    stop_grace_period: 60s
    depends_on:
      postgres:
        condition: service_healthy
      gotenberg:
        condition: service_healthy
    env_file: stack.env
    environment:
      SPRING_PROFILES_ACTIVE: prod
      JOBS_MODE: web
      # The caddy edge below is the backend's only HTTP peer, so it is the trusted proxy by default (security
      # finding #80); without it every request would appear to come from the edge container. Override only
      # for a custom proxy chain.
      SECURITY_TRUSTED_PROXIES: ${SECURITY_TRUSTED_PROXIES:-caddy}
      BACKUP_LOCAL_DIR: /app/data/backups
    volumes:
      - backend_uploads:/app/data/uploads
      - backend_pdfs:/app/data/pdfs
      - backend_backups:/app/data/backups
      - backend_geoip:/app/data/geoip
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 45s
    cpus: ${BACKEND_CPUS:-0}
    # Heap auto-scales to 70% of this limit (MaxRAMPercentage); default 1536m → ~1 GB heap,
    # fits the 4 GB-VM profile. Raise BACKEND_MEM_LIMIT for heavier load (see resource docs).
    mem_limit: ${BACKEND_MEM_LIMIT:-1536m}
    restart: unless-stopped
    logging: *json-file-logging

  backup-worker:
    # Scheduled backups: same image as the backend, JOBS_MODE=backup-only; archives go to the backups volume.
    image: ghcr.io/lesisty7/quotenode/quotenode-api@sha256:0ed701f952c27ea0e1db168a00de75facb231f7c6d5f6b4f0f3b77ef98d4f140
    depends_on:
      postgres:
        condition: service_healthy
      backend:
        condition: service_healthy
    env_file: stack.env
    environment:
      SPRING_PROFILES_ACTIVE: prod
      JOBS_MODE: backup-only
      BACKUP_LOCAL_DIR: /app/data/backups
      # Worker runs pg_dump in a shell (out-of-JVM) and never does web/import heap work,
      # so it needs little heap. On this small 768m container the ~350 MB fixed non-heap
      # cost makes the global MaxRAMPercentage=70 (538 MB heap → 888 MB total) unsafe.
      # Cap heap lower so heap_max + non-heap stays well under the limit.
      JAVA_OPTS: "-XX:MaxRAMPercentage=45.0 -XX:+UseG1GC -XX:G1PeriodicGCInterval=300000"
    volumes:
      - backend_uploads:/app/data/uploads
      - backend_pdfs:/app/data/pdfs
      - backend_backups:/app/data/backups
      - backend_geoip:/app/data/geoip
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
      interval: 15s
      timeout: 10s
      retries: 5
      # JVM boots a large Spring context (CPU-bound); the grace window must outlast
      # cold start to avoid a false-unhealthy restart loop under load.
      start_period: 300s
    # CPU is a ceiling (idle cost ~0); give the worker enough to boot fast and to run
    # pg_dump + age-encryption/compression bursts without throttling. Idles near zero CPU.
    cpus: ${WORKER_CPUS:-0}
    # Default 832m: measured backup peak (JVM idle + pg_dump + tar + gzip) is ~607 MiB, so
    # this keeps a ~27% margin. Do NOT set WORKER_MEM_LIMIT below ~768m or backups risk OOM.
    mem_limit: ${WORKER_MEM_LIMIT:-832m}
    restart: unless-stopped
    logging: *json-file-logging

  frontend:
    # Web UI: the static build served by Caddy, reached through the caddy entry point.
    image: ghcr.io/lesisty7/quotenode/quotenode-frontend@sha256:40a1cdc4fca5cebd9f43d34daef4ba059a88000ff08af821e199566f07260606
    depends_on:
      backend:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:80/"]
      interval: 15s
      timeout: 5s
      retries: 3
    cpus: ${FRONTEND_CPUS:-0}
    # Prod frontend is Caddy serving the static build (measured ~46 MiB peak under load); 96m is ample.
    # CPU is a free ceiling, so headroom for concurrent connections costs nothing at idle.
    mem_limit: ${FRONTEND_MEM_LIMIT:-96m}
    restart: unless-stopped
    logging: *json-file-logging

  caddy:
    # Entry point: the only published ports (HTTP_PORT/HTTPS_PORT, default 80/443), TLS for DOMAIN, routing, security headers.
    image: ghcr.io/lesisty7/quotenode/quotenode-frontend@sha256:40a1cdc4fca5cebd9f43d34daef4ba059a88000ff08af821e199566f07260606
    # The released frontend image carries the edge config (frontend/caddy/Caddyfile.edge) and the Cloudflare
    # ranges, so the edge needs no host files. Same image digest as the frontend service.
    command: ["caddy", "run", "--config", "/etc/caddy/Caddyfile.edge", "--adapter", "caddyfile"]
    depends_on:
      backend:
        condition: service_healthy
      frontend:
        condition: service_healthy
    environment:
      # Site address for frontend/caddy/Caddyfile.edge: a public host name enables automatic HTTPS; ":80" or
      # "http://host" serves plain HTTP on a trusted LAN. Required: an empty site address is not a valid config.
      DOMAIN: ${DOMAIN:?set DOMAIN to the public host name, or :80 for plain HTTP on a LAN}
      # Optional: address(es) of an operator reverse proxy in front of this edge (default: trust none).
      EDGE_TRUSTED_PROXIES: ${EDGE_TRUSTED_PROXIES:-}
    ports:
      - "${HTTP_PORT:-80}:80"
      - "${HTTPS_PORT:-443}:443"
      - "${HTTPS_PORT:-443}:443/udp"      # HTTP/3 (QUIC)
    volumes:
      - caddy_data:/data
      - caddy_config:/config
    # caddy is the single ingress (TLS, HTTP/3/QUIC, proxying all traffic); give it
    # cores for handshake/encryption bursts under load. CPU idle cost ~0.
    cpus: ${CADDY_CPUS:-0}
    # 96m fits the 4 GB / light-traffic profile. Under heavy TLS load (many concurrent
    # handshakes, large QUIC buffers) raise CADDY_MEM_LIMIT — this ingress is untested at scale.
    mem_limit: ${CADDY_MEM_LIMIT:-96m}
    restart: unless-stopped
    logging: *json-file-logging

# Persistent data: database, uploads, generated PDFs, local backup archives, GeoIP database and the entry
# point's certificates/config. Docker prefixes each name with the Compose project name (by default the
# directory name), so keep the project name across upgrades.
volumes:
  postgres_data:
  backend_uploads:
  backend_pdfs:
  backend_backups:
  backend_geoip:
  caddy_data:
  caddy_config:

Pour revenir en arrière, restaurez la sauvegarde des volumes avec la définition de stack enregistrée. Ne démarrez jamais l’ancienne définition sur une base de données que la nouvelle version a déjà migrée.

Coolify

Remplacez la définition Compose de la ressource par le docker-compose.coolify.yml du nouveau paquet (Edit Compose File) et déployez. Coolify récupère les nouvelles images avant d’arrêter les conteneurs en cours. Voir Installation avec Coolify.

Installations antérieures aux paquets de version

Si vous avez installé QuoteNode avec ces guides avant l’existence des paquets de version (un docker-compose.yml écrit à la main avec des images :latest), mettez à jour dans le même répertoire avec les mêmes commandes : upgrade.sh fait la sauvegarde avec les outils de la nouvelle version sur le projet Compose et les volumes de votre installation, si bien qu’aucun répertoire operator/ ni service de sauvegarde n’est nécessaire au préalable. Avant prepare, ajoutez ces paramètres à .env ; l’installation en cours ne les utilise pas encore :

  • DOMAIN configure désormais le nouveau point d’entrée (caddy) : un nom d’hôte public obtient automatiquement HTTPS ; pour du HTTP simple en LAN ou sur un portable, utilisez DOMAIN=http://<adresse> (par exemple http://192.168.1.20 ou http://localhost).
  • Si les ports 80/443 sont occupés, définissez HTTP_PORT / HTTPS_PORT au lieu de modifier le fichier Compose.

Le paquet conserve les noms de volumes des guides précédents (postgres_data, backend_uploads, backend_pdfs), vos données sont donc réutilisées. Lancez upgrade.sh depuis le même répertoire (ou conservez le même nom de stack dans Portainer) : un autre nom de projet démarrerait avec des volumes vides.

Si une migration arrête la mise à jour

Une migration peut refuser de s’exécuter lorsqu’elle trouve des données qu’elle n’a pas le droit de modifier d’elle-même. Le backend ne démarre alors pas et cette migration ne change rien — elle est entièrement annulée et ne laisse rien à réparer dans l’historique des migrations. Des migrations antérieures de la même mise à jour peuvent déjà avoir été appliquées : votre base se trouve donc juste avant l’étape refusée et non à la version de départ. Rien ne presse et aucune donnée n’est perdue.

Lisez la raison dans le journal :

docker compose logs backend | grep -i "cannot enforce"

Pour les affectations de sections d’offres, l’image contient une réparation guidée qui fonctionne sans backend actif — elle montre les offres concernées et vous laisse choisir leur sort. Voir Résolution des problèmes d’installation.

N’utilisez pas flyway repair ni baseline pour contourner une migration refusée. Ils ne réparent pas les données, et une migration bloquée ne laisse rien à réparer.

Comme des migrations antérieures peuvent déjà être appliquées, un échec de démarrage à lui seul ne permet jamais de revenir aux images précédentes — voir Revenir en arrière.

Vérification après la mise à jour

  1. Ouvrez /health — la réponse est UP.
  2. Ouvrez /actuator/info : son commitSha est égal au commitSha du nouveau release.json.
  3. Connectez-vous et vérifiez la nouvelle version dans Admin > Licence.
  4. Créez une offre de test et générez un PDF.
  5. Ouvrez un lien public pour vérifier le routage.
  6. Si SMTP est configuré, envoyez un e-mail de notification de test.

Revenir en arrière

N’exécutez jamais docker compose down -v — cela supprime toutes les données, y compris la base de données.

upgrade.sh rollback ne revient à la définition enregistrée par prepare que si c’est sûr : le point de contrôle doit appartenir à cette installation, le schéma de la base doit être exactement celui enregistré — un échec de démarrage ne le prouve pas, des migrations antérieures peuvent déjà être validées — et chaque image précédente doit encore être celle qui tournait. Sinon, il refuse et ne change rien :

../next/operator/upgrade.sh rollback
  • Autorisé : les docker-compose.yml, .env et release.json enregistrés reviennent et les images précédentes démarrent sans téléchargement ; les services ajoutés par la nouvelle version sont supprimés, les volumes sont conservés.
  • Refusé : ne démarrez pas les images précédentes à la main. Si une migration a refusé, corrigez dans la nouvelle version (voir Si une migration arrête la mise à jour) ou restaurez la sauvegarde faite avant la mise à jour — base de données et fichiers comme un tout — comme décrit dans Sauvegarde et restauration. La restauration vérifie l’archive et sa compatibilité avant de modifier quoi que ce soit et conserve une copie de sécurité jusqu’à avoir vérifié le résultat.
  • Les installations antérieures aux paquets de version reviennent en arrière de la même manière. Après un refus, restaurez la sauvegarde de ../quotenode-backups avec operator/restore.sh de cette version ; la version met à jour les données restaurées à son démarrage.

Format de version

QuoteNode utilise le versionnage sémantique avec un suffixe de canal :

  • v0.9.0-alpha — développement précoce
  • v0.9.0-beta — bêta publique
  • v0.9.0-rc — version candidate
  • v0.9.0 — version stable

Un libellé de version n’est jamais réutilisé pour d’autres images. release.json et https://quotenode.dev/releases/latest.json indiquent la version, le canal, le libellé, le commit et les digests des images de la version.

Last reviewed: Recently