# Architecture ``` tensorchord/vchord-postgres:pgN-v1.1.1 PostgreSQL N, VectorChord, pgvector (Debian 12) │ ▼ base ........ apt-get upgrade : PostgreSQL (mineure), pgvector, Debian ├──▶ builder ... en-têtes du serveur + compilation de TimescaleDB │ │ bibliothèques et scripts SQL ▼ ▼ final ....... TimescaleDB copié, PostGIS (apt), scripts de démarrage │ ▼ gitea.killinger.fr/maxime.killinger/postgres-ts-vectors:pgN ``` Le même Dockerfile produit une image par version majeure de PostgreSQL, choisie par l'argument `PG_VERSION`. Les trois étapes s'enchaînent ainsi parce que le serveur et ses en-têtes doivent avoir la même version ([0002](decisions/0002-paquets-a-jour-et-en-tetes-du-serveur.md)). ## Fichiers | Fichier | Rôle | |---|---| | `Dockerfile` | Construction de l'image, en trois étapes | | `init-extensions.sh` | Création des extensions à l'initialisation de la base | | `docker-entrypoint-wrapper.sh` | Point d'entrée : droits du volume, puis point d'entrée de l'image `postgres` | | `tests.sh` | Tests de l'image, en local et en CI | | `tests/test-*.sql` | Contrôles joués sur une base neuve, un fichier par extension ou combinaison | | `tests/reprise-*.sql` | Données créées par l'image précédente, puis relues par la nouvelle | | `build.sh` | Construction locale d'une version | | `.gitea/workflows/docker.yml` | CI : construction, tests, publication, mises à jour nocturnes | ## D'où vient chaque composant | Composant | Source | Version | |---|---|---| | PostgreSQL | image de base, puis `apt-get upgrade` (dépôt PGDG) | dernière mineure de la majeure | | VectorChord | image de base | `VCHORD_VERSION` du Dockerfile | | pgvector | image de base, puis `apt-get upgrade` (dépôt PGDG) | dernière disponible | | TimescaleDB | compilé depuis l'étiquette Git de la version | `TIMESCALEDB_VERSION` du Dockerfile | | PostGIS | paquet `postgresql-N-postgis-3` (dépôt PGDG) | dernière disponible | Pourquoi cet assemblage : [0001](decisions/0001-image-vectorchord-et-timescaledb-compile.md). Pourquoi deux versions sont épinglées et pas les autres : [0003](decisions/0003-versions-de-timescaledb-et-vectorchord-epinglees.md). ## Étapes de construction - **`base`** part de l'image de VectorChord et met tous ses paquets à niveau. L'argument `APT_REFRESH` ne sert qu'à invalider le cache de cette couche : sa valeur est affichée, rien d'autre ne la lit. - **`builder`** part de `base`, installe les outils de compilation et les en-têtes du serveur dans la version exacte du serveur installé, puis compile TimescaleDB et l'installe dans `/tmp/timescaledb`. - **`final`** part de `base`, reçoit de `builder` les bibliothèques (`/usr/lib/postgresql/`) et les scripts SQL (`/usr/share/postgresql/`) de TimescaleDB, installe PostGIS, copie les deux scripts de démarrage et déclare la sonde de santé. Aucun outil de compilation n'y entre. Labels de l'image : titre, description, source, auteur, licence et image de base sont dans le Dockerfile ; révision, version, date et clé `fr.killinger.apt-refresh` sont posés par la CI ([exploitation/publication.md](exploitation/publication.md)). ## Démarrage du conteneur 1. `docker-entrypoint-wrapper.sh` démarre en root, crée `/var/lib/postgresql` s'il manque, en donne la propriété à `postgres` et le ferme aux autres utilisateurs. Un volume monté arrive en effet avec les droits de son hôte. 2. Il passe la main à `docker-entrypoint.sh`, le point d'entrée de l'image officielle `postgres`, qui prend l'identité `postgres`. 3. Sur un volume vide, ce point d'entrée initialise la base, démarre un serveur temporaire et exécute `init-extensions.sh`, qui crée `timescaledb`, `vector`, `vchord`, `postgis` et `postgis_topology` dans la base `POSTGRES_DB`. Sur un volume déjà initialisé, rien de cela n'a lieu. 4. Le serveur définitif démarre avec la commande de l'image : `postgres -c shared_preload_libraries=timescaledb,vchord`. Les deux bibliothèques doivent être préchargées pour que leurs extensions fonctionnent. La sonde de santé interroge `pg_isready` toutes les 30 secondes, avec l'utilisateur et la base du conteneur. ## Données | Étiquette | Volume déclaré par l'image | Répertoire des données (`PGDATA`) | |---|---|---| | `pg15`, `pg16`, `pg17`, `latest` | `/var/lib/postgresql/data` | `/var/lib/postgresql/data` | | `pg18` | `/var/lib/postgresql` | `/var/lib/postgresql/18/docker` | Ces emplacements sont ceux de l'image officielle `postgres`, que l'image de base reprend. À partir de PostgreSQL 18, le répertoire porte le numéro de la version majeure, pour que deux versions cohabitent dans le même volume pendant un `pg_upgrade`. Une image `pg18` qui trouve un volume monté sur `/var/lib/postgresql/data` refuse de démarrer. Passer d'une version majeure à la suivante n'est pas un changement d'étiquette : les données d'une version ne sont pas lisibles par une autre sans `pg_upgrade` ou sauvegarde et restauration ([0006](decisions/0006-latest-reste-sur-postgresql-17.md)).