Aller au contenu principal

Docker

Le chemin Docker exécute le framework comme conteneur en face d'un conteneur PostgreSQL séparé, avec le dépôt liberty-apps monté en volume. Ajouter Traefik dans le même compose pour le TLS et un nom d'hôte lisible (traité à part dans Traefik) ; piloter la pile visuellement avec Portainer.

Cette page déroule la pile minimale autonome — Liberty + PostgreSQL — sans TLS. Les ajouts de niveau production se superposent par-dessus.


Prérequis

OutilVersion
Docker Engine≥ 24
Docker Composev2 (le plugin docker compose, pas le binaire docker-compose déprécié)
Disque hôte~2 Go pour l'image du framework + le volume de la BDD
RAM hôte≥ 1 Go libre pour le conteneur du framework + Postgres

Un hôte Linux (Ubuntu / Debian / Rocky / Alpine) est la cible classique. Docker Desktop sur macOS / Windows convient pour des essais locaux.


Étape 1 — Cloner le dépôt des apps

Le framework lit sa configuration dans liberty-apps :

git clone https://github.com/<your-org>/liberty-apps.git /opt/liberty/apps

Arborescence après le clone :

/opt/liberty/apps/
├── config/ ← the TOML files (LIBERTY_APPS_DIR points here)
│ ├── app.toml
│ ├── connectors.toml
│ ├── dictionary.toml
│ ├── screens.toml
│ ├── menus.toml
│ ├── dashboards.toml
│ ├── charts.toml
│ └── jobs.toml
└── plugins/ ← your Python plugins (importable at startup)
└── <your-plugin>/

Pour une installation neuve sans dépôt d'apps existant, partir du dépôt modèle vide — cloner, renommer, pousser vers votre propre Git.


Étape 2 — Écrire docker-compose.yml

Une pile minimale avec Liberty + PostgreSQL :

# /opt/liberty/docker-compose.yml
services:

postgres:
image: postgres:16
container_name: liberty-postgres
restart: unless-stopped
environment:
POSTGRES_DB: liberty
POSTGRES_USER: liberty
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U liberty -d liberty"]
interval: 10s
timeout: 5s
retries: 5

liberty:
image: ghcr.io/fblettner/liberty-next:latest
container_name: liberty
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
LIBERTY_APPS_DIR: /apps/config
LIBERTY_MASTER_KEY: ${LIBERTY_MASTER_KEY}
LIBERTY_LICENSE_KEY: ${LIBERTY_LICENSE_KEY:-}
LIBERTY_JWT_SECRET: ${LIBERTY_JWT_SECRET}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET:-}
# Database URL — uses the postgres service above
DATABASE_URL: postgresql+asyncpg://liberty:${POSTGRES_PASSWORD}@postgres:5432/liberty
volumes:
- /opt/liberty/apps:/apps:ro # the apps repo, read-only
- liberty-logs:/var/log/liberty
ports:
- "8000:8000"

volumes:
postgres-data:
liberty-logs:

Trois points à noter :

DétailPourquoi
:ro sur le montage des apps.Liberty n'écrit jamais dans le dépôt des apps — le passer en lecture seule évite qu'un processus incontrôlé corrompe la configuration.
depends_on avec service_healthy.Liberty attend que PostgreSQL accepte les connexions avant de démarrer ; sans cela, la course à la première connexion échoue.
Secrets via les variables ${...}.Ne jamais inscrire un secret en dur dans docker-compose.yml. Utiliser le fichier .env ci-dessous.

Étape 3 — Écrire .env

Frère de docker-compose.yml :

# /opt/liberty/.env
POSTGRES_PASSWORD=replace-with-a-real-password
LIBERTY_MASTER_KEY=$(openssl rand -hex 32)
LIBERTY_JWT_SECRET=$(openssl rand -hex 32)
LIBERTY_LICENSE_KEY=
ANTHROPIC_API_KEY=
OIDC_CLIENT_SECRET=

Générer les deux valeurs aléatoires une seule fois et les sauvegarder — perdre la clé maîtresse, c'est perdre toutes les valeurs ENC: sur disque ; perdre le secret JWT invalide tous les jetons signés (pas catastrophique mais chaque utilisateur doit se reconnecter).

Permission fichierPropriétaireMode
.envroot (ou l'utilisateur Docker)0600
chmod 600 /opt/liberty/.env

Étape 4 — Démarrer la pile

cd /opt/liberty
docker compose up -d

Cela télécharge les images, démarre PostgreSQL, attend qu'il soit en bonne santé, puis démarre Liberty. Après 10 à 30 secondes :

docker compose ps
# NAME STATUS PORTS
# liberty-postgres Up 30s (healthy) 5432/tcp
# liberty Up 20s 0.0.0.0:8000->8000/tcp

curl http://localhost:8000/health
# {"status":"ok"}

Étape 5 — Amorcer le premier utilisateur

Le framework démarre sans aucun utilisateur — la connexion est impossible. Amorcer un superutilisateur :

docker compose exec liberty liberty-admin init-db --superuser admin
# Prompts for a password (8+ chars).

Désormais, http://<host>:8000/ affiche l'écran de connexion — se connecter avec admin.


Étape 6 — Confirmer l'installation

Un test rapide :

VérificationComment
Liberty répond.curl http://<host>:8000/health{"status":"ok"}.
Le dossier des plugins a été trouvé.`docker compose logs liberty
La connexion Postgres fonctionne.`docker compose logs liberty
La page de connexion s'affiche.Ouvrir http://<host>:8000/ dans un navigateur.
La connexion fonctionne.Utiliser l'utilisateur admin de l'étape 5.

En cas d'échec sur l'un de ces points, se rendre à la section Dépannage ci-dessous.


Volumes — ce qu'il faut sauvegarder

La pile comporte deux volumes :

VolumeCe qu'il contientStratégie de sauvegarde
postgres-dataLes métadonnées de Liberty (authentification, jobs, verrous, historique d'exécution) et vos données opérationnelles si vous pointez les pools opérationnels sur le même Postgres.pg_dump planifié. Restauration en rejouant le dump dans un Postgres neuf.
liberty-logsLes journaux applicatifs.Suivre avec docker compose logs liberty. Rétention longue durée : router vers votre backend de journalisation (Loki, ELK, Datadog).

Le dépôt liberty-apps sur l'hôte est un checkout git — le sauvegarder avec git, pas avec Docker.

Le fichier .env qui porte la clé maîtresse et le secret JWT est votre sauvegarde la plus critique. Sans lui, impossible de restaurer les secrets à partir d'une sauvegarde de postgres-data.


Mises à jour

Pour récupérer une image plus récente du framework :

cd /opt/liberty
docker compose pull liberty
docker compose up -d liberty

pull récupère la nouvelle image sans redémarrer. up -d liberty échange le conteneur (5 à 10 secondes d'indisponibilité). Postgres reste intact.

Pour la procédure de mise à niveau complète, migrations de BDD et retour arrière inclus, voir Mise à niveau.


Dépannage

Le conteneur Liberty sort immédiatement

docker compose logs liberty

Causes fréquentes :

Ligne de journalCauseCorrection
LIBERTY_APPS_DIR not setLa variable d'environnement n'a pas été propagée.Vérifier le bloc environment: dans docker-compose.yml.
Could not connect to databasePostgres n'est pas encore en bonne santé, ou DATABASE_URL est faux.Vérifier docker compose ps ; vérifier que le mot de passe correspond entre Postgres et la variable.
Plugins directory not foundLe montage des apps est absent ou vide.Vérifier que /opt/liberty/apps/plugins/ existe ; vérifier le chemin de montage dans compose.
Master key not set alors que vous avez des valeurs ENC:La variable de la clé maîtresse est vide.Renseigner LIBERTY_MASTER_KEY dans .env.

La page de connexion s'affiche, mais la connexion échoue

Le magasin d'utilisateurs du framework est vide tant que liberty-admin init-db n'a pas été exécuté. Le relancer.

Les modifications du dépôt des apps ne sont pas prises en compte

Le framework prend en compte les éditions de .toml via Paramètres → Recharger dans l'UI (ou POST /admin/reload). Pour les modifications de plugins Python, redémarrer :

docker compose restart liberty

Le port 8000 est occupé

Changer le port côté hôte dans docker-compose.yml :

ports:
- "8001:8000" # external:internal

Le conteneur continue d'écouter sur 8000 en interne ; seul le port de l'hôte change.


La suite

  • Traefik — ajouter le TLS et un nom d'hôte lisible.
  • Portainer — gestion visuelle de la pile.
  • Production — multi-réplicas, routage des journaux, durcissement.
  • Mise à niveau — la procédure de mise à niveau.