PG18 de retour, mises à jour nocturnes, tests de reprise et documentation
🚀 Docker Build and Push / build-and-push (15) (push) Successful in 5m29s
🚀 Docker Build and Push / build-and-push (16) (push) Successful in 6m10s
🚀 Docker Build and Push / build-and-push (17) (push) Successful in 5m20s
🚀 Docker Build and Push / build-and-push (18) (push) Successful in 5m21s

Image
- Étape `base` commune : tous les paquets sont mis à niveau (PostgreSQL à la
  dernière mineure, pgvector, Debian). L'image de base de VectorChord restait
  figée à la version de sa publication.
- En-têtes du serveur épinglés sur la version du serveur installé. PG18 avait
  été retiré parce que TimescaleDB, compilé avec des en-têtes 18.6, était chargé
  par un serveur 18.3 (`undefined symbol: palloc0_mul`).
- Sonde de santé avec l'utilisateur et la base du conteneur : en `postgres`,
  elle écrivait une erreur FATAL au journal dès que POSTGRES_USER était défini.
- Label `base.name` corrigé : il reprenait la version du paquet au lieu de la
  version majeure.

CI
- PG18 ajouté à la matrice.
- Exécution nocturne : apt est interrogé dans l'image publiée ; elle n'est
  reconstruite et republiée que s'il lui reste des mises à jour, sinon elle est
  seulement testée. Lancement manuel possible.
- `docker-build.yml` supprimé : l'ancien workflow à actions externes tournait
  encore à chaque push, en double de `docker.yml`.
- `paths-ignore` : un push de documentation seule ne lance pas la CI.
- Labels `version`, `url` et `fr.killinger.apt-refresh`.

Tests
- `tests.sh`, la même commande en local et en CI : utilisateur et base autres
  que `postgres`, version majeure du serveur, présence des cinq extensions,
  redémarrage, et reprise d'une base créée par l'image publiée.

Documentation
- README en vitrine, CLAUDE.md, docs/architecture.md,
  docs/exploitation/publication.md, six décisions, docs/a-faire.md.
This commit is contained in:
maxime.killinger committed 2026-10-02 17:55:42 +02:00
1 parent 2a0f84e81a
commit 7de55c5655
18 files changed
+956 -242

No files matched your search

+99
View File
@@ -0,0 +1,99 @@
# 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)).