Aller au contenu principal

Installation avec Docker

Cette procédure utilise les conteneurs Compose et Ofelia pour planifier les traitements. Ne pas installer en parallèle les services systemd ou les anciens CRON sur les mêmes données. Les scripts métier et leurs journaux sont communs aux deux installations.

Prérequis et organisation​

Utiliser Docker Engine et Docker Compose 2.24 ou supérieur, un espace disque suffisant pour le PBF, sa conversion, PostgreSQL et les rapports, et un reverse proxy HTTPS pour l'application publique. Sous Windows, travailler dans le système de fichiers Linux de WSL : les fichiers de configuration doivent conserver leurs permissions POSIX et leurs fins de ligne LF.

Placer le dépôt dans /opt/lebontag-v2 et exécuter les commandes suivantes depuis ce répertoire, avec un compte autorisé à utiliser Docker. Le socket Docker donne des pouvoirs importants au planificateur : son montage en lecture seule n'interdit pas les opérations de l'API Docker. Ne pas l'exposer sur le réseau.

Les données PostgreSQL sont dans le volume nommé pgdata du projet Compose. Les fichiers OSM, rapports et logs restent dans osm/ et log/ du dépôt. Les images contiennent le code et les dépendances ; les secrets sont montés ou fournis à l'exécution, exclus du contexte de build.

Profil / serviceRôle
Sans profil : db, webappBase et application
toolsInitialisation et attribution du premier compte administrateur, sur commande
automationPipeline, intégration, découpage, nettoyage et Ofelia
emailsEnvois des notifications par le worker HTTP, facultatifs

docker compose --env-file .env.db up -d seul ne démarre pas les traitements automatiques. Les commandes ciblant explicitement un service peuvent le lancer sans activer tout son profil.

1. Préparer les configurations​

Pour une nouvelle installation :

cp .env.db.example .env.db
cp .env.production.local.example .env.production.local
mkdir -p osm/source osm/replication osm/integration/runs log
chmod 700 osm/integration/runs
chmod 600 .env.db .env.production.local

Ne pas remplacer les fichiers de configuration existants lors d'une mise à jour. Aucun changement récursif de propriétaire du projet n'est nécessaire. Les workers de données fonctionnent sous root dans leurs conteneurs ; le serveur web et le worker email utilisent le compte node. Le dossier log/ doit être traversable et ses journaux lisibles par le serveur web (par exemple répertoire 755, fichiers 644, sans y placer de secrets).

Dans .env.db, définir les mots de passe administrateur PostgreSQL et applicatif, distincts. Le rôle applicatif est osm. Pour une base neuve, conserver POSTGRES_DB=lebontag. Dans .env.production.local :

DB_HOST=db
DB_PORT=5432
DB_NAME=lebontag
DB_USER=osm
DB_PASS=MEME_VALEUR_QUE_LBT_DB_PASSWORD_DANS_ENV_DB
DB_SSL=false
DB_SCHEMA=lebontag
DB_SRID=4326
LBT_CAPTURE_RELATION_CONTEXT=1

Renseigner également AUTH_URL, AUTH_SECRET, les fournisseurs d'authentification, les secrets email et les URL OSM_DATA_URL / OSM_REPL_SERVER_URL. Le PBF, son fichier .state.txt et les diffs doivent correspondre au même extrait. Voir Configuration. Utiliser des valeurs littérales sans interpolation de variables ; des valeurs hexadécimales conviennent aux nouveaux mots de passe. Ne pas supposer qu'une variable d'un fichier env sera interpolée depuis un autre.

Les ports publiés sont limités à 127.0.0.1 : PostgreSQL 5432 et application 3000. Un reverse proxy sur l'hôte peut joindre http://127.0.0.1:3000. Un proxy conteneurisé doit partager un réseau explicitement configuré. Ne pas utiliser localhost pour joindre PostgreSQL depuis l'application : le nom interne est db.

Pour personnaliser le nom du projet ou les ports, utiliser le même fichier .env.db :

COMPOSE_PROJECT_NAME=lebontag-v2
LBT_POSTGRES_PORT=5432
LBT_WEB_PORT=3000
LBT_POSTGRES_IMAGE=pgrouting/pgrouting:17-3.5-main

Conserver le même COMPOSE_PROJECT_NAME pour toutes les commandes, y compris le planificateur ; éviter un -p différent. Une mise à jour applicative ne doit pas changer la version majeure PostgreSQL du volume.

2. Autoriser explicitement la cible​

Tout est défini dans .env.production.local : connexion, mode, limites, cible et emails. Aucun fichier sous config/ n’est nécessaire. Calculer sha256sum osm/style/default.style et ajouter le JSON sur une ligne, entre quotes simples :

LBT_INTEGRATION_MODE=check
LBT_INTEGRATION_LIMIT=500
LBT_INTEGRATION_TIMEOUT=600
LBT_INTEGRATION_OBJECT_LIMIT=1000
LBT_INTEGRATION_TARGET='{"format":1,"host":"db","port":"5432","database":"lebontag","user":"osm","schema":"lebontag","reference_schema":"osm2pgsql","reference_prefix":"osm","srid":2154,"output":"pgsql","osm2pgsql_version":"2.2.0","style_sha256":"SHA256_DU_STYLE"}'

Remplacer le hash et adapter la cible aux valeurs réellement autorisées ; host=db et port=5432 désignent la connexion interne Docker. Les contrôles du style, de la version, de la base et du rôle restent obligatoires. Voir Configuration des services. Ne pas générer cette autorisation automatiquement à partir des DB_*. Le fichier ne doit pas être modifiable par le groupe ou les autres utilisateurs.

3. Construire et initialiser une installation neuve​

docker compose --env-file .env.db --profile tools --profile automation config --quiet
docker compose --env-file .env.db --profile tools --profile automation build
docker compose --env-file .env.db up -d db
docker compose --env-file .env.db logs -f db

Quitter le suivi des logs une fois PostgreSQL prêt et l'initialisation SQL terminée sans erreur. Sur un volume vide uniquement, l'image PostgreSQL exécute sql/init.sql, sql/lebontag_v2.sql, puis le paramétrage du mot de passe et des droits du rôle osm. Le build fournit un vrai venv Python et osm2pgsql 2.2.0 ; aucun osm2pgsql ni venv n'est nécessaire sur l'hôte.

docker compose --env-file .env.db run --rm initializer

L'initialiseur télécharge le PBF en flux, vérifie que le fichier d'état n'a pas changé pendant le téléchargement, charge les données et initialise la séquence seulement après succès. Il refuse une base déjà chargée ou utilisée. En cas d'échec après le début du chargement, examiner les journaux et réparer ou restaurer la base avant toute reprise : ne pas activer le pipeline sur une initialisation incomplète.

Après le message de succès :

docker compose --env-file .env.db up -d webapp

Créer le premier compte en se connectant à l'application. Vérifier qu'il s'agit bien du compte devant devenir administrateur avant d'exécuter :

docker compose --env-file .env.db run --rm make-first-user-admin

Configurer les emprises, groupes métier, groupes d'objets, droits et options de découpage dans l'application. Le pipeline n'est pas encore planifié.

4. Contrôler puis activer les traitements​

Lancer une première chaîne de réplication et un contrôle d'intégration :

docker compose --env-file .env.db run --rm pipeline python3 lbt-docker-job.py pipeline
docker compose --env-file .env.db run --rm integration python3 lbt-docker-job.py integration --mode check

Le pipeline exécute dans cet ordre : téléchargement, ingestion, auto-validation, intersections des emprises. Une erreur arrête la chaîne. L'intégration conserve les refus, attentes et contextes incomplets ; ne pas forcer les états en base pour supprimer ces blocages.

Consulter le suivi en administration et les rapports dans osm/integration/runs/. Un résultat blocked ou un lot partiel peut être normal. Le wrapper Docker accepte les codes métier 0 et 2 comme systemd ; il conserve le code réel dans sa sortie et les rapports. Un code 0 du planificateur ne signifie donc pas que tous les objets sont intégrés.

Après vérification de la cible et des contrôles :

docker compose --env-file .env.db run --rm integration python3 lbt-docker-job.py integration --mode execute

Le découpage est ensuite demandé avec la raison after-integration ; son propre script vérifie si une reconstruction est nécessaire et si l'option est activée. Un échec du découpage est journalisé séparément et n'annule pas une intégration déjà confirmée. Il n'y a pas de relance automatique d'append après un état incertain.

Mettre ensuite LBT_INTEGRATION_MODE=execute dans .env.production.local, puis :

docker compose --env-file .env.db --profile automation up -d pipeline integration segmentation cleaner
# Vérifier les journaux de démarrage, puis activer le planificateur :
docker compose --env-file .env.db --profile automation up -d ofelia
TraitementPlanification Europe/Paris
Pipeline completToutes les heures
Intégration03:30
DécoupageAprès intégration si nécessaire, et chaque nuit à 04:15
Nettoyage05:30
Emails, si activésToutes les 5 minutes

Au démarrage du conteneur segmentation, un contrôle demande aussi le calcul si aucune publication réussie ne couvre la dernière échéance de 04:15. Cette reprise concerne le découpage ; le redémarrage d'un conteneur ne déclenche pas un append. Le découpage reste facultatif selon db_pgr_update.

Les verrous métier sont conservés. Les tâches Docker empêchent également les chevauchements du même job ; pipeline, intégration et découpage ne doivent pas être lancés en parallèle par un ancien CRON ou un service hôte.

Après changement des fichiers env, recréer les conteneurs concernés, puis redémarrer Ofelia pour qu'il retrouve leurs nouveaux identifiants. Un simple restart ne recharge pas les variables d'environnement :

docker compose --env-file .env.db --profile automation up -d --force-recreate integration segmentation
docker compose --env-file .env.db restart ofelia

5. Emails facultatifs​

Le worker lit .env.production.local, comme l’application.

Dans ce même fichier, configurer LBT_DIGEST_WORKER_URL avec l'URL publique HTTPS joignable depuis le conteneur, et LBT_EMAIL_DIGEST_SECRET avec la même valeur que l'application. http://localhost:3000 désignerait le conteneur email lui-même ; http://webapp:3000 n'est pas accepté par la politique HTTPS du worker. Configurer aussi SMTP et les abonnements dans l'application.

docker compose --env-file .env.db --profile emails build email-digests
docker compose --env-file .env.db --profile emails up -d email-digests
docker compose --env-file .env.db restart ofelia

Le worker appelle la route protégée de l'application. Avec ce fichier partagé, il reçoit aussi les autres variables applicatives : il doit être considéré comme un processus de confiance.

6. Exploitation et mise à jour​

Les sorties des commandes planifiées sont dans docker compose --env-file .env.db logs ofelia. Les journaux métier restent dans log/, les rapports dans osm/integration/runs/ et les états en base. Le suivi d'administration reste la référence pour les blocages et la dernière publication réussie. En cas de needs_review, arrêter la planification d'intégration, inspecter le lot et utiliser la procédure de reprise contrôlée ; ne pas répéter l'append.

Pour mettre à jour une installation existante :

  1. Relever le nom du projet Compose, l'image PostgreSQL et le volume réellement utilisés (docker compose --env-file .env.db ls, docker volume ls, docker inspect). Conserver ce nom dans COMPOSE_PROJECT_NAME, la base existante (parfois postgres) et la même version majeure PostgreSQL.
  2. Arrêter Ofelia, attendre la fin des opérations actives en consultant leurs journaux et PostgreSQL, puis arrêter les workers et l'application avec l'ancienne configuration. Ne pas interrompre un append en cours. Désactiver également les anciens CRON ou timers qui écrivent dans cette base.
  3. Sauvegarder la base entière, les fichiers de réplication, le style et les configurations. Ne jamais utiliser docker compose --env-file .env.db down -v pour une mise à jour.
  4. Installer les nouveaux fichiers. Suivre Mises à jour pour la chaîne SQL correspondant à la version de départ et l'éventuel rechargement explicitement requis. Dans Docker, reconstruire les images remplace l'installation de paquets et les services systemd de la procédure native.
  5. Appliquer chaque SQL dans l'ordre, en remplaçant le nom de base si nécessaire :
docker compose --env-file .env.db up -d db
docker compose --env-file .env.db exec -T db psql -U postgres -d lebontag -v ON_ERROR_STOP=1 < sql/update_2.7.4_to_2.8.0.sql

Adapter aussi -U si l'administrateur PostgreSQL porte un autre nom. Ne pas rejouer lebontag_v2.sql sur une base existante.

  1. Si l'ancienne installation utilisait postgres pour l'application, définir LBT_DB_PASSWORD dans .env.db, recréer db pour charger cette variable, puis configurer le rôle applicatif :
docker compose --env-file .env.db up -d db
docker compose --env-file .env.db exec -T db bash /docker-entrypoint-initdb.d/002_app_role.sh

Les objets LeBonTag doivent appartenir à osm, comme dans les SQL fournis ; contrôler les éventuels objets locaux créés sous un autre propriétaire. Modifier ensuite DB_USER=osm et DB_PASS dans .env.production.local, ainsi que LBT_INTEGRATION_TARGET. Sur un volume existant, changer POSTGRES_PASSWORD dans un fichier ne change pas le mot de passe du serveur.

  1. Construire les images, contrôler la configuration et redémarrer webapp. Ne pas lancer initializer lors d'une mise à jour : la séquence et le référentiel existants doivent être conservés, sauf procédure explicite de rechargement.
  2. Refaire le contrôle manuel de l'étape 4. Après succès, démarrer les workers et Ofelia. Utiliser --remove-orphans avec les profils effectivement activés pour retirer les anciens services Compose (par exemple updater). Vérifier les rapports et les logs après le premier passage.
docker compose --env-file .env.db --profile tools --profile automation build
docker compose --env-file .env.db --profile automation config --quiet
docker compose --env-file .env.db up -d webapp
# Après contrôle et avec LBT_INTEGRATION_MODE=execute :
docker compose --env-file .env.db --profile automation up -d --remove-orphans
# Si les emails sont utilisés, activer aussi --profile emails.

Les unités systemd ne sont pas installées sur l'hôte Docker. Garder le moteur Docker activé au démarrage ; les services persistants utilisent restart: unless-stopped.

Développement​

docker compose --env-file .env.db -f docker-compose.yml -f docker-compose.dev.yml up -d webapp monte les sources pour Next.js. Adapter .env.development.local avec DB_HOST=db et le port interne 5432. Pour isoler les données, utiliser un autre répertoire et un autre COMPOSE_PROJECT_NAME. Ne pas activer les workers automatiques sur les volumes de production depuis cet environnement.