Files
EVCS/deploy/historisation/compose.yaml
Tallagrand Thierry d41b0a0eb0 Grafana ne doit pas etre otage de la sante de PostgreSQL
`condition: service_healthy` rendait le demarrage de Grafana dependant du
healthcheck de PostgreSQL (intervalle 1 min). Grafana n'a pourtant besoin
d'aucune base pour demarrer, seulement pour repondre a une requete : la
condition ajoutait un mode de panne sans contrepartie, et un outil de
diagnostic doit surtout etre disponible quand quelque chose va mal.
Ramene a un simple ordre de demarrage.

Procedure corrigee sur deux points constates au deploiement reel :
- `sudo` est obligatoire sur DSM (socket Docker inaccessible autrement) ;
- le `git pull` que j'avais indique n'a aucun sens : /volume2/projects cote
  Syno et /mnt/projects cote poste sont le meme dossier (export NFS depuis
  10.10.10.22), il n'existe qu'une seule copie du depot.

Configuration verifiee en la rejouant dans un conteneur local, volume nomme
compris : deux sources de donnees, trois tableaux dans le dossier EVCS,
database ok, aucune erreur de provisionnement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
2026-09-04 08:20:40 +02:00

181 lines
7.1 KiB
YAML

# Mémoire de mesures EVCS — à déployer sur le SECOND Synology (10.10.10.22).
#
# Deux bases, deux rôles distincts, décidés le 04/09/2026 :
#
# postgres (proposition A) — ce que n8n CALCULE : sorties du bilan,
# décisions du contrôleur, prévision telle qu'elle a été publiée.
# Relationnel, donc capable de stocker un vecteur de 24 valeurs,
# une raison en texte, un événement daté — et de les JOINDRE.
#
# influxdb (proposition B) — ce que Home Assistant OBSERVE : chaque
# changement d'état, à la résolution native, y compris les entités
# auxquelles personne n'a encore pensé. C'est ce qui a manqué le
# 03/09, quand les modes des chargeurs MPPT se sont révélés être le
# bon signal alors que personne ne les enregistrait.
#
# ⚠️ NE PAS héberger sur 10.10.10.17 : cette machine porte déjà Home Assistant,
# n8n, openclaw et open-webui. Une mémoire qui meurt avec la machine qu'elle
# documente ne sert à rien (cf. HANDOFF §32).
#
# Mise en service :
# cd /volume2/projects/EVCS/EVCS/deploy/historisation
# bash preparer-env.sh (genere .env avec des secrets aleatoires)
# docker compose up -d
# docker compose logs -f
#
# Vérification :
# docker compose exec postgres psql -U evcs -d evcs -c '\dt'
# curl -s http://10.10.10.22:8086/health
#
# Volumes NOMMÉS et non bind-mounts : le démon Docker de DSM refuse un
# bind-mount dont le dossier hôte est absent, et une base de données sur un
# partage réseau est une mauvaise idée (verrouillage, latence, fsync).
services:
postgres:
image: postgres:16-alpine
container_name: evcs-postgres
restart: always
ports:
# 5433 et non 5432 : DSM fait deja tourner son propre PostgreSQL sur le
# port standard, pour ses services internes. On ne le deloge pas — on se
# met a cote. Ce port n'est publie que pour l'analyse depuis un poste de
# travail ; l'historisation, elle, passe par le reseau interne.
- "5433:5432"
env_file:
- .env
environment:
- TZ=Europe/Paris
- POSTGRES_USER=evcs
- POSTGRES_DB=evcs
# POSTGRES_PASSWORD vient de historisation.env
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- evcs-pgdata:/var/lib/postgresql/data
# Appliqué UNE SEULE FOIS, à la création de la base. Pour faire évoluer
# le schéma ensuite, écrire une migration et la passer à psql.
- ./schema.sql:/docker-entrypoint-initdb.d/10-schema.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U evcs -d evcs"]
interval: 1m
timeout: 10s
retries: 5
influxdb:
image: influxdb:2.7-alpine
container_name: evcs-influxdb
restart: always
ports:
# Home Assistant, sur 10.10.10.17, écrit ici.
- "8086:8086"
env_file:
- .env
environment:
- TZ=Europe/Paris
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_ORG=airtria
- DOCKER_INFLUXDB_INIT_BUCKET=evcs
# Rétention 0 = illimitée sur le seau brut. Le sous-échantillonnage se
# fait par tâches (voir README), pas en jetant la donnée d'entrée.
- DOCKER_INFLUXDB_INIT_RETENTION=0
# DOCKER_INFLUXDB_INIT_USERNAME / _PASSWORD / _ADMIN_TOKEN : env file
volumes:
- evcs-influx-data:/var/lib/influxdb2
- evcs-influx-config:/etc/influxdb2
healthcheck:
test: ["CMD", "influx", "ping"]
interval: 1m
timeout: 10s
retries: 5
# Alimentation de PostgreSQL depuis Home Assistant. Volontairement PAS
# depuis n8n : tout ce que n8n calcule, il le publie deja dans des helpers HA
# — les lire ici donne la meme information sans toucher aux trois workflows
# de production ni creer d'identifiant dans n8n.
historisation:
image: node:22-alpine
container_name: evcs-historisation
restart: always
working_dir: /app
depends_on:
postgres:
condition: service_healthy
volumes:
# Depot en LECTURE SEULE : ce service n'ecrit que dans la base.
- /volume2/projects/EVCS/EVCS:/app:ro
env_file:
- .env
environment:
- TZ=Europe/Paris
- HA_URL=http://10.10.10.17:8123
# Nom de service sur le reseau interne du compose : ni IP en dur, ni
# dependance au port publie sur l'hote.
- PGHOST=postgres
- PGPORT=5432
- PGUSER=evcs
- PGDATABASE=evcs
# Reprise du mot de passe unique par substitution : il n'y a qu'un seul
# secret PostgreSQL a renseigner, pas deux a tenir egaux a la main.
- PGPASSWORD=${POSTGRES_PASSWORD}
- HISTORISE_INTERVAL_S=60
command: ["node", "tools/historise-evcs.mjs"]
# Consultation des DEUX bases au meme endroit. Grafana ne stocke rien de la
# mesure : il interroge PostgreSQL et InfluxDB a la demande. Le perdre ne
# perd aucune donnee — c'est une fenetre, pas un coffre.
grafana:
image: grafana/grafana-oss:11.3.0
container_name: evcs-grafana
restart: always
depends_on:
# Ordre de demarrage SEULEMENT, volontairement pas `service_healthy` :
# Grafana n'a pas besoin de PostgreSQL pour demarrer, seulement pour
# repondre a une requete. Le rendre otage de la sante d'une autre base,
# c'est ajouter un mode de panne sans contrepartie — et un outil de
# diagnostic doit surtout etre disponible quand quelque chose va mal.
- postgres
ports:
# 3001 et NON 3000 : quelque chose ecoute deja sur 3000 sur cette
# machine (verifie avant d'ecrire cette ligne, comme le port 5432 deja
# pris par le PostgreSQL interne de DSM).
- "3001:3000"
env_file:
# Deux fichiers : les secrets de la pile (mot de passe admin Grafana,
# mot de passe PostgreSQL) et ceux du depot (role de lecture, jeton
# InfluxDB). Aucun secret n'est duplique — c'etait le piege du
# POSTGRES_PASSWORD/PGPASSWORD tenus egaux a la main.
- .env
- ../../.env
environment:
- TZ=Europe/Paris
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
# Rien ne sort de la maison : ni telemetrie, ni verification de version,
# ni recuperation de plugins. Cette installation doit fonctionner
# pendant une coupure Internet d'orage (HANDOFF §32).
- GF_ANALYTICS_REPORTING_ENABLED=false
- GF_ANALYTICS_CHECK_FOR_UPDATES=false
- GF_ANALYTICS_CHECK_FOR_PLUGIN_UPDATES=false
- GF_NEWS_NEWS_FEED_ENABLED=false
- GF_USERS_ALLOW_SIGN_UP=false
- GF_DATE_FORMATS_DEFAULT_TIMEZONE=Europe/Paris
volumes:
# Provisionnement en LECTURE SEULE : sources de donnees et tableaux de
# bord viennent du depot git, comme le code des nodes n8n (regle R2).
- ./grafana/provisioning:/etc/grafana/provisioning:ro
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
# Base interne de Grafana : sessions, preferences, copies de travail.
- evcs-grafana-data:/var/lib/grafana
healthcheck:
test: ["CMD-SHELL", "wget -q -O- http://localhost:3000/api/health || exit 1"]
interval: 1m
timeout: 10s
retries: 5
volumes:
evcs-pgdata:
evcs-influx-data:
evcs-influx-config:
evcs-grafana-data: