Aller au contenu principal

Mise à jour

Une mise à jour Liberty est un simple changement de tag. Chaque mode de déploiement — Light / Full Compose, Docker Swarm, pipx — se résume aux trois mêmes gestes : prendre un instantané des volumes, récupérer la nouvelle image (ou le wheel), laisser la pile se réconcilier. Les migrations de schéma sont embarquées dans la nouvelle image ; l'entrypoint les applique au démarrage. Plus de migrate-db manuel, plus de checkout du code source, plus de reconstruction.

Cette page couvre le contrat de versionnage, la procédure de mise à jour par mode de déploiement, le test de fumée post-mise à jour et le chemin de rollback.


Vue d'ensemble

Séquence de mise à jour — identique pour tous les modes de déploiement1 · SAUVEGARDE./backup.sh — assurance en 5 s2 · PIN + PULLLIBERTY_IMAGE_TAG + pull3 · UP -dl'entrypoint exécute init-db4 · TEST DE FUMÉE/info + connexion + poolsUne mise à jour Compose propre représente ~30 s d'indisponibilité. En Swarm rolling = zéro indisponibilité dès que les replicas > 1.

Contrat de versionnage

Liberty suit un schéma proche du semver :

IncrémentÀ quoi s'attendre
Patch (0.42.00.42.1)Corrections de bug uniquement. Aucun changement de configuration. Aucune migration de base.
Mineur (0.42.x0.43.0)Nouvelles fonctionnalités. Configuration rétrocompatible. Migrations de base additives uniquement — nouvelles tables / colonnes du framework ; les lignes existantes restent intactes. Les champs obsolètes émettent un avertissement pendant une mineure.
Majeur (0.x1.0)Ruptures possibles. Détaillées une par une dans les notes de version ; un guide de migration est publié en parallèle.

Les notes de version de chaque version se trouvent aux côtés du tag d'image — à lire avant tout passage d'une mineure ou d'une majeure.


Fonctionnement des migrations de base

L'entrypoint du conteneur (et l'unité systemd pipx, si elle est câblée) exécute liberty-admin init-db à chaque démarrage. Cette commande est :

  • Sans effet en double. L'exécuter deux fois ne fait rien la seconde fois.
  • Additive. Elle crée les nouvelles tables framework apportées par une version plus récente, ajoute les colonnes manquantes et laisse les lignes existantes intactes.
  • Embarquée. Les deltas de schéma sont livrés à l'intérieur de l'image / du wheel — aucune étape migrate-db séparée à lancer, aucun fichier SQL à appliquer, aucun job de migration à planifier.

Récupérer une image plus récente, redémarrer la pile — le schéma suit.

Aucune étape de migration manuelle

L'ancienne commande liberty-admin migrate-db a disparu. Tout ce qu'elle faisait est désormais intégré au init-db exécuté au démarrage.


Épingler le tag d'image en production

Les fichiers compose livrés utilisent par défaut :latest pour qu'une installation neuve démarre sur la dernière version. La production doit épingler un tag spécifique dans .env afin qu'un pull inattendu ne fasse pas avancer la pile vers une nouvelle mineure sans prévenir :

.env
LIBERTY_IMAGE_TAG=0.2.0

Avancer en modifiant la valeur puis en relançant pull && up -d. Revenir en arrière en repositionnant le tag précédent et en faisant la même chose.

Tag dans .envComportement
latestChaque pull peut basculer vers l'image publiée la plus récente — pratique en pré-production, risqué en production.
0.2.0 (épinglé)pull est sans effet dès que le cache local possède le tag. Les mises à jour ne surviennent que sur édition de .env.

Toujours sauvegarder en premier

backup.sh produit un instantané tar de chaque volume nommé Liberty dans un répertoire horodaté. L'opération prend quelques secondes et fait la différence entre une mise à jour ratée et une mise à jour ratée réversible.

cd /opt/liberty-next/release
./backup.sh # → ./backups/YYYY-MM-DD_HHMMSS/
./backup.sh /mnt/nas/liberty # vers un emplacement hors hôte
./backup.sh --layout full # uniquement les volumes du déploiement Full

Détails complets sur le format de sauvegarde, les commandes de restauration et une entrée cron hebdomadaire : Docker → Backups.


Procédure de mise à jour — Light / Full (Compose)

Identique pour les deux modes. Deux commandes équivalentes ; au choix.

Option A — relancer ./install.sh <layout> (recommandé)

cd /opt/liberty-next/release

./backup.sh # 1 — instantané (systématique)
./install.sh full # 2 — détecte le .env existant, ignore la génération de secrets,
# récupère les nouvelles images, lance `docker compose up -d`,
# attend l'état healthy, affiche le résumé

install.sh se relance sans risque. Quand .env existe déjà, il :

  • Journalise .env already exists — keeping it et ignore la génération des secrets (aucun risque de régénérer LIBERTY_MASTER_KEY et de perdre les valeurs chiffrées).
  • Lance docker compose pull puis docker compose up -d sur la chaîne COMPOSE_FILE définie dans .env.
  • Attend que le healthcheck de liberty-next (/info) passe à healthy.
  • Affiche le résumé — la ligne Sign in to Liberty as indique désormais password unchanged from the original install (le mot de passe admin du premier démarrage était à usage unique — l'identifiant existant continue de fonctionner). Le mot de passe pgAdmin est réimprimé depuis .env à titre de rappel.

Conserver le même mode de déploiement que celui utilisé à l'installation — en passer un autre (./install.sh light sur une installation full ou l'inverse) démarre le mauvais fichier compose.

Option B — docker compose nu (effet identique)

cd /opt/liberty-next/release

./backup.sh # 1 — instantané
docker compose pull # 2 — récupération de la nouvelle image (COMPOSE_FILE sélectionne les bons fichiers)
docker compose up -d # 3 — recréation des conteneurs ; l'entrypoint exécute init-db

# 4 — test de fumée
curl -s http://127.0.0.1:8000/info

Effet identique, sortie plus discrète, pas d'impression de résumé. À privilégier en CI ou dès que les commodités interactives d'install.sh deviennent gênantes.

Jamais de -f après l'installation

COMPOSE_FILE dans .env porte la chaîne complète (docker-compose.full.yml:docker-compose.tls-letsencrypt.yml:docker-compose.apps.yml après install.sh --ssl letsencrypt --apps ...). Passer manuellement -f docker-compose.full.yml surcharge cette chaîne et écarte silencieusement les overlays TLS + apps — le prochain up -d les supprime. S'en tenir aux commandes nues docker compose pull / up -d, ou utiliser ./install.sh. Voir Docker → Discipline COMPOSE_FILE.

Ce que fait up -d : Compose détecte que le digest de l'image a changé, recrée le conteneur liberty-next sur place, remonte les mêmes volumes nommés, redémarre. Le nouvel entrypoint exécute liberty-admin init-db, puis se met à servir. Indisponibilité totale : ~30 s sur un hôte tiède.

Les autres services de la pile (Postgres, pgAdmin, Portainer, Traefik) ne sont pas recréés tant que leur propre tag d'image n'a pas bougé — pull agit par service et up -d ne recrée que ceux dont la spécification a changé.

Ce qui survit à la mise à niveau

Tout ce que l'opérateur a touché. Compose recrée le conteneur liberty-next ; les volumes (et le bind mount des apps quand l'overlay apps est actif) se rattachent intacts au nouveau conteneur.

ÉtatSe trouve dansPréservé ?
.env (master key, secret JWT, mots de passe Postgres / pgAdmin)release/.env sur l'hôteIntact.
Base framework (authentification, historique d'exécutions Nomaflow, données des apps sous licence)Volume pg-dataPostgres n'est pas recréé tant que son tag d'image n'a pas bougé.
TOMLs édités par l'opérateur (app.toml + connectors.toml + screens.toml + menus.toml + dashboards / charts / dictionary)Volume liberty-configMonté sur /app/config dans le nouveau conteneur.
Clé de licence, clé d'API Anthropic, secret client OIDCapp.toml (valeurs chiffrées ENC: avec la master key d'installation)Se trouve dans liberty-config. Le nouveau conteneur déchiffre avec la LIBERTY_MASTER_KEY inchangée du .env.
Certificat Let's Encrypt + état ACMEVolume traefik-acmePas de nouveau cycle ACME ; les rate limits LE ne sont pas consommés.
Enregistrements de serveurs pgAdmin + préférencesVolume pgadmin-dataPréservé.
État PortainerVolume portainer-dataPréservé.
Bundle d'apps sous licence (TOMLs Nomasx-1 / Nomajde + code des plugins)Bind mount ./apps/ sur l'hôte (défini par APPS_HOST_PATH dans .env)Le mount se rattache au nouveau conteneur sur /apps:ro.
LIBERTY_ADMIN_PASSWORD du premier démarrageAffiché une seule fois à l'installation initiale, jamais écrit dans .envL'utilisateur admin existant conserve son mot de passe. Perdu ? docker exec liberty-next liberty-admin reset-admin-password.

:latest vs tag épinglé

Ligne .envCe que pull récupère
# LIBERTY_IMAGE_TAG=latest (commenté — défaut)Compose utilise :latest par défaut. Chaque pull peut basculer vers l'image publiée la plus récente — acceptable en pré-production, risqué en production.
LIBERTY_IMAGE_TAG=7.0.21 (épinglé)pull est sans effet dès que le cache local possède le tag. Les mises à jour ne surviennent que sur incrément de la valeur + pull && up -d.

Pour épingler : décommenter la ligne dans .env, fixer la version, lancer ./install.sh full (ou docker compose pull && up -d).

Quand la wheel d'apps sous licence change aussi

./install.sh full (ou docker compose pull) ne rafraîchit que l'image liberty-next — pas le bundle d'apps présent sur le bind mount ./apps/. Pour une mise à jour de la wheel liberty-apps (nouvelle version Nomasx-1 / Nomajde), passer par l'installeur dédié :

./install-apps.sh /path/to/new-liberty_apps-X.Y.Z.whl
docker compose restart liberty-next # prend en compte les TOMLs rafraîchis

L'installeur de wheel se relance sans risque — les TOML édités par l'opérateur dans ./apps/config/ sont préservés sauf passage de --force-config. Voir Deploy prebuilt apps → Updating the apps later.

La plupart des mises à jour framework ne concernent que liberty-next — aucune wheel d'apps à rafraîchir.


Procédure de mise à jour — Docker Swarm

Deux approches. À choisir.

Option A — rolling update sur le seul service liberty-next

./backup.sh
docker service update --image ghcr.io/fblettner/liberty-next:0.2.0 liberty_liberty-next

Swarm fait rouler le service selon son update_config (order: start-first, parallelism: 1). La nouvelle tâche démarre, passe les health checks, puis l'ancienne tâche est arrêtée :

Replicas liberty-nextIndisponibilité
> 1Aucune. Swarm démarre une nouvelle tâche, attend qu'elle soit saine, puis draine l'ancienne.
1 (par défaut)Brève fenêtre (~10 s) le temps que la nouvelle tâche chauffe — start-first la minimise sans pouvoir l'éliminer.

Les autres services de la pile (pg, pgadmin, portainer, traefik) ne sont pas touchés.

Option B — bumper .env + relancer le script de déploiement

./backup.sh
# éditer .env : LIBERTY_IMAGE_TAG=0.2.0
./deploy-swarm.sh

docker stack deploy réconcilie la spécification complète — chaque service dont l'image ou l'environnement a changé est roulé. Relancer ./deploy-swarm.sh EST le mécanisme de mise à jour en Swarm ; c'est le même script qui a servi à installer.

Utiliser l'option B quand plusieurs tags de services sont bumpés en même temps ou quand l'environnement d'un autre service a été modifié.

Rollback en Swarm

Swarm conserve la spécification précédente de chaque service :

docker service rollback liberty_liberty-next

Le rollback inverse le dernier service update (ou l'effet du dernier stack deploy sur ce service). Si la nouvelle image a appliqué un delta de schéma et que des écritures y ont eu lieu, restaurer depuis l'instantané backup.sh avant de revenir en arrière — voir Rollback ci-dessous.


Procédure de mise à jour — pipx

./backup.sh # si un script de sauvegarde est conservé à côté (recommandé)
pipx upgrade liberty-next
sudo systemctl restart liberty-next # si exécuté sous systemd

pipx upgrade remplace le wheel dans le venv isolé. Le service redémarré exécute liberty-admin init-db au démarrage — la même synchronisation de schéma sans risque que le chemin conteneur.

Pour la définition de l'unité systemd, l'EnvironmentFile et la vérification post-installation : Python server → Run under systemd.


Liste de vérification du test de fumée

Cinq minutes, à chaque mise à jour.

ContrôleCommentÀ confirmer
Bascule de versioncurl http://<host>/info"version" correspond au tag qui vient d'être tiré.
ConnexionSe connecter en tant qu'admin.L'authentification locale fonctionne toujours.
Chargement d'écranOuvrir au moins un écran d'app.La grille se remplit, pas de 500.
Pools connectésSettings → PoolsChaque pool s'affiche comme connected.
Scheduler à jourSettings → Jobs — choisir un job planifié.Sa dernière exécution est succeeded (ou pending — pas failed).
Licence acceptée (quand LIBERTY_LICENSE_KEY est défini)Settings → LicenseAffiche accepted avec le bon nom de client.

Un contrôle en échec doit stopper le déploiement et déclencher la procédure de rollback.


Rollback

La même simplicité s'applique à l'envers : repointer sur le tag précédent, redémarrer. La nuance se trouve dans la base — les deltas de schéma additifs ne sont pas annulés automatiquement. En pratique :

Nouveau schéma…Marche à suivre
Purement additif (nouvelles tables / colonnes — le cas courant)Revenir à l'ancienne image. L'ancien framework ignore les colonnes supplémentaires et continue de fonctionner. Aucune restauration BD nécessaire.
Non additif (renommage de colonne, contrainte ajoutée, valeur migrée)Restaurer le volume depuis l'instantané backup.sh avant de revenir à l'ancienne image. Les notes de version signalent chaque migration non additive.

Light / Full (Compose)

# éditer .env : LIBERTY_IMAGE_TAG=0.1.0 (le tag précédent)
docker compose pull # COMPOSE_FILE sélectionne les bons fichiers
docker compose up -d

Si le schéma a avancé et que les données doivent aussi revenir en arrière, restaurer d'abord le volume concerné depuis ./backups/<timestamp>/ — voir Docker → Backups pour la commande de restauration par volume.

Swarm

docker service rollback liberty_liberty-next

Même mise en garde : si le schéma a divergé, restaurer le volume pg-data (après ./deploy-swarm.sh --rm) avant de revenir en arrière sur le service, puis redéployer.

pipx

pipx install liberty-next==0.1.0 --force
sudo systemctl restart liberty-next

Conseils

  • Étager la mise à jour. Exécuter le nouveau tag sur une copie de production pendant une journée avant de basculer en prod. Le coût de prolonger un déploiement défectueux est largement supérieur à celui d'un redémarrage supplémentaire.
  • Lire les notes de version. La plupart des mises à jour passent inaperçues — pull && up -d puis le test de fumée valide. Les rares exceptions sont signalées explicitement. Deux minutes de lecture évitent une heure de débogage.
  • Éviter de sauter plusieurs mineures d'un coup quand c'est possible. Passer 0.40 → 0.43 peut enchaîner des dépréciations disparues en chemin. Aller version par version garde les avertissements gérables.
  • Épingler en production. :latest convient pour la pré-production ; la production doit épingler LIBERTY_IMAGE_TAG afin qu'un pull de routine ne surprenne pas avec une nouvelle mineure.
  • Surveiller les journaux après redémarrage. Une ligne WARN sur un champ obsolète annonce que la prochaine mineure cassera — corriger tout de suite, pas plus tard.

Pour aller plus loin

  • Docker → Backups — le format d'instantané, les commandes de restauration et l'entrée cron hebdomadaire référencés ci-dessus.
  • Python server — la recette pipx + systemd sur laquelle la mise à jour atterrit.
  • Production — durcissement, OIDC, épinglage du scheduler — la forme de déploiement dans laquelle les mises à jour atterrissent.