Démarrage du backend : connexion à postgres impossible
Lors d'un redémarrage du CT petit-rapporteur, le backend n'arrive pas à se connecter à la DB postgres, alors que pourtant elle est bien démarrée. En regardant plus en détail les logs, on voit la chose suivante, dans le backend :
2022-10-28T07:02:36.028502454Z INFO: Will watch for changes in these directories: ['/backend']
2022-10-28T07:02:36.055434103Z INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
2022-10-28T07:02:36.055456461Z INFO: Started reloader process [7] using StatReload
2022-10-28T07:02:36.687444750Z INFO: Started server process [9]
2022-10-28T07:02:36.687468493Z INFO: Waiting for application startup.
2022-10-28T07:02:36.700785990Z --- DB CONNECTION ERROR ---
2022-10-28T07:02:36.700804399Z [Errno 111] Connect call failed ('172.20.0.3', 5432)
2022-10-28T07:02:36.700808829Z --- DB CONNECTION ERROR ---
2022-10-28T07:02:36.700863731Z INFO: Application startup complete.
Et sur postgres :
2022-10-28T07:02:35.962834874Z
2022-10-28T07:02:35.962869189Z PostgreSQL Database directory appears to contain a database; Skipping initialization
2022-10-28T07:02:35.962877637Z
2022-10-28T07:02:36.860225582Z 2022-10-28 07:02:36.860 UTC [1] LOG: starting PostgreSQL 13.8 on x86_64-pc-linux-musl, compiled by gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219, 64-bit
2022-10-28T07:02:36.860262072Z 2022-10-28 07:02:36.860 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2022-10-28T07:02:36.860266371Z 2022-10-28 07:02:36.860 UTC [1] LOG: listening on IPv6 address "::", port 5432
2022-10-28T07:02:36.969711195Z 2022-10-28 07:02:36.969 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2022-10-28T07:02:37.093162600Z 2022-10-28 07:02:37.093 UTC [21] LOG: database system was shut down at 2022-10-28 07:02:11 UTC
2022-10-28T07:02:37.161688668Z 2022-10-28 07:02:37.161 UTC [1] LOG: database system is ready to accept connections
Le problème vient du fait que l'image docker postgres est faite pour démarrer une première fois, faire son initialisation (et/ou un upgrade de la DB si on change de version majeure), puis redémarrer pour passer en mode "connexions acceptées, tout roule". Le PR utilise bien le depends
de docker pour que le backend démarre après la DB, mais du coup le premier démarrage déclenche le depends
, et on peut se retrouver dans une situation où la DB démarre (première fois), ça déclenche le démarrage du PR, puis la DB redémarre, et le PR essaie de se connecter pendant ce "trou", et échoue.
En cherchant un peu, je suis tombé sur la solution suivante, rajouter un healthcheck
au docker-compose ainsi, qui va vérifier que PG est réellement prêt à accepter des connexions.
--- docker-compose.base.yml 2022-11-02 10:03:11.671776086 +0100
+++ docker-compose.base.yml.healthcheck 2022-11-02 10:03:06.031655512 +0100
@@ -12,7 +12,8 @@
env_file:
- ./backend/.env
depends_on:
- - db
+ db:
+ condition: service_healthy
frontend:
build:
@@ -30,6 +31,11 @@
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./backend/.env
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
nginx:
build:
Ça soulève aussi un autre (potentiel) problème (mais je peux faire une autre issue si besoin) : si le backend perd la connexion à la DB, du coup le PR arrive dans un état cassé, vu qu'il n'essaie jamais de se reconnecter. À priori c'est pas un soucis, je vois pas dans quel cas il perd la connexion à la DB, mais je préfère soulever le problème (au cas où)