From 859e51ea20be19cff3e8864c33767e25cc931192 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 07:30:47 +0000 Subject: [PATCH 1/2] =?UTF-8?q?Faire=20r=C3=A9parer=20le=20mot=20de=20pass?= =?UTF-8?q?e=20d'amor=C3=A7age=20par=20le=20conteneur=20de=20la=20base?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `POSTGRES_PASSWORD` n'est lu qu'à la création du volume. Un volume né d'un déploiement antérieur garde le mot de passe d'alors, et plus rien dans la pile ne peut le corriger : ni l'application, ni `db-init`, tous deux refusés à l'entrée. Le symptôme visible — un P1000 sur `planflow_app` — désigne le mauvais coupable, et la seule issue était du SQL à la main. La seule position d'où la réparation est possible est l'intérieur du conteneur de la base, où PostgreSQL accepte la socket locale sans mot de passe. Le service y réaligne donc le compte d'amorçage sur la valeur de la pile à chaque démarrage, avant de céder la main au point d'entrée officiel. Le SQL passe par l'entrée standard et non par `-c` : `psql -c` n'interpole pas les variables, si bien que `:'pw'` y partait littéralement — mesuré, « syntax error at or near ":" ». Par l'entrée standard, c'est psql qui met le mot de passe entre guillemets, et une apostrophe dans le mot de passe ne casse rien. Vérifié avec un mot de passe en contenant une. Éprouvé en exécutant le corps de la commande contre un vrai serveur, avec un point d'entrée factice : la reprise attend le serveur, le réalignement aboutit, et le mot de passe est bien posé. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Cr9dkEHwbDgkWPnyGj1Rjv --- docker-compose.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 01ce1a6..94a0127 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,6 +19,41 @@ services: # Deterministic collation: ordering of employee names must not depend on # the host locale, or exports differ between machines. LANG: C.UTF-8 + # Réaligne le mot de passe du compte d'amorçage à **chaque** démarrage. + # + # `POSTGRES_PASSWORD` n'est lu qu'à la création du volume. Un volume né d'un + # déploiement antérieur garde donc le mot de passe d'alors, et plus rien + # dans la pile ne peut le corriger : ni l'application, ni `db-init`, tous + # deux refusés à l'entrée. La seule position d'où la réparation est possible + # est l'intérieur de ce conteneur, où PostgreSQL accepte la socket locale + # sans mot de passe. + # + # Sans cela, une installation ayant connu deux valeurs de mot de passe ne + # redémarre plus jamais sans SQL à la main — et le symptôme, un `P1000` sur + # le rôle applicatif, désigne le mauvais coupable. + # + # Le SQL passe par l'entrée standard et non par `-c` : `psql -c` n'interpole + # pas les variables, si bien que `:'pw'` y serait envoyé littéralement. Par + # l'entrée standard, c'est psql qui met le mot de passe entre guillemets — + # une apostrophe dans le mot de passe ne casse donc rien. + command: + - sh + - -c + - | + ( + tentative=0 + while [ $$tentative -lt 60 ]; do + if echo "ALTER USER \"$$POSTGRES_USER\" WITH PASSWORD :'pw';" \ + | psql -q -v ON_ERROR_STOP=1 -v pw="$$POSTGRES_PASSWORD" \ + -U "$$POSTGRES_USER" -d postgres >/dev/null 2>&1; then + echo "[db] Mot de passe du compte d'amorçage réaligné sur la pile." + break + fi + tentative=$$((tentative + 1)) + sleep 1 + done + ) & + exec docker-entrypoint.sh postgres volumes: - db-data:/var/lib/postgresql/data # Crée le rôle applicatif à la première initialisation du volume. From 607de2a1e7ee204f0cb7302601fcc641daed85e1 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 07:31:55 +0000 Subject: [PATCH 2/2] =?UTF-8?q?Attacher=20la=20base=20au=20r=C3=A9seau=20d?= =?UTF-8?q?u=20reverse-proxy,=20=C3=A0=20la=20demande?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'exploitant veut `db` sur `nginx_default`. Ce n'est pas requis pour que l'application joigne la base — les deux partagent déjà `interne`, et le journal le prouve : « password authentication failed for user "planflow" » suppose que le nom a été résolu, la connexion établie et le dialogue d'authentification engagé. Une absence de réseau commun donnerait une résolution de nom impossible, pas un refus d'identifiants. Le commentaire dit donc ce que cela coûte : la base devient joignable par tous les conteneurs que sert ce proxy, `POSTGRES_PASSWORD` cesse d'être une formalité, et le nom `db` publié sur un réseau partagé peut entrer en collision avec celui d'une autre pile. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Cr9dkEHwbDgkWPnyGj1Rjv --- docker-compose.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 94a0127..302f4b8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -63,12 +63,21 @@ services: interval: 5s timeout: 5s retries: 10 - # Volontairement absente du réseau externe : elle n'a besoin que de - # l'application. L'y attacher exposerait la base à tout ce que le - # reverse-proxy héberge, et le mot de passe par défaut deviendrait alors un - # vrai problème. + # `interne` suffit à l'application : les deux services s'y joignent déjà, et + # rien de ce que fait la base ne passe par le reverse-proxy. + # + # `nginx_default` est ajouté à la demande de l'exploitant. Il faut en + # mesurer la portée : la base devient joignable par **tous** les conteneurs + # que sert ce proxy, et non plus par la seule application. + # `POSTGRES_PASSWORD` cesse alors d'être une formalité — sa valeur par + # défaut ne protège plus rien d'utile, il faut la changer. + # + # Autre effet à connaître : le nom `db` est publié sur ce réseau partagé. Un + # autre service nommé `db` qui s'y attacherait rendrait la résolution + # ambiguë pour les deux piles. networks: - interne + - nginx_default # Le conteneur reste sur 5432 pour l'application, et le port hôte est publié # sur un port non commun, configurable : plusieurs instances PostgreSQL # coexistent sur le même serveur, et s'en tenir au 5432 par défaut les