🚀 Docker Build and Push / build-and-push (15) (push) Successful in 2m58s
🚀 Docker Build and Push / build-and-push (16) (push) Successful in 3m39s
🚀 Docker Build and Push / build-and-push (17) (push) Successful in 3m37s
🚀 Docker Build and Push / build-and-push (18) (push) Successful in 3m36s
- TIMESCALEDB_VERSION passe de 2.28.3 à 2.30.2. Vérifié pour 16, 17 et 18 : compilation, tests, et reprise d'une base créée par l'image publiée après `ALTER EXTENSION timescaledb UPDATE`. - TimescaleDB 2.29 a retiré PostgreSQL 15 (`Unsupported PostgreSQL version` à la compilation) : `pg15` garde 2.28.3 par TIMESCALEDB_VERSION_PG15. - Décision 0007, tableau et badge du README, procédure de changement de version. Une base existante refuse toute requête sur la nouvelle image tant que l'extension n'est pas mise à niveau : voir docs/exploitation/publication.md.
8.6 KiB
8.6 KiB
postgres-ts-vectors — consignes
Image Docker de PostgreSQL avec TimescaleDB, VectorChord, pgvector et PostGIS, publiée pour PostgreSQL 15 à 18 dans le registre Gitea. Le dépôt ne contient que la construction de l'image, ses scripts de démarrage et ses tests. Architecture : docs/architecture.md. Choix de conception : docs/decisions/. Points ouverts : docs/a-faire.md.
Commandes
# Construire une version (PG_VERSION : 15, 16, 17 ou 18 ; 18 par défaut)
docker build --build-arg PG_VERSION=17 -t postgres-ts-vectors:pg17 .
# Rejouer la mise à niveau des paquets, que le cache garderait sinon telle quelle
docker build --build-arg PG_VERSION=17 --build-arg APT_REFRESH=$(date +%F) -t postgres-ts-vectors:pg17 .
# Essayer une autre version de TimescaleDB sans toucher au Dockerfile (X.Y.Z : étiquette Git)
docker build --build-arg PG_VERSION=17 --build-arg TIMESCALEDB_VERSION=X.Y.Z -t postgres-ts-vectors:essai .
# Tests de l'image
./tests.sh postgres-ts-vectors:pg17
# Tests, plus reprise d'une base créée par l'image publiée
docker pull gitea.killinger.fr/maxime.killinger/postgres-ts-vectors:pg17
./tests.sh postgres-ts-vectors:pg17 gitea.killinger.fr/maxime.killinger/postgres-ts-vectors:pg17
# Mises à jour qu'apt propose à une image publiée (ce que la CI regarde chaque nuit)
docker run --rm --entrypoint sh gitea.killinger.fr/maxime.killinger/postgres-ts-vectors:pg17 -c \
'apt-get update -qq && apt-get -s upgrade --with-new-pkgs | grep ^Inst'
- Tests :
tests.sh IMAGE [IMAGE_PRECEDENTE], en local comme en CI. Il démarre l'image avec un utilisateur et une base autres quepostgres, vérifie que le serveur a la version majeure de l'étiquette, jouetests/test-*.sqldans l'ordre, redémarre le serveur, puis, si une image précédente est donnée, crée une base avec elle (tests/reprise-1-semis.sql) et la reprend avec l'image testée (tests/reprise-2-controle.sql). Conteneurs et volume sont jetables. - Lint : aucun outil configuré.
- CI (
.gitea/workflows/docker.yml) : construit, teste et publie les quatre versions à chaque push surmain, sauf si tous les fichiers modifiés sont des.mdou sousdocs/(paths-ignore). Chaque nuit, elle teste les images publiées et reconstruit celles qui ont des mises à jour. Détail : docs/exploitation/publication.md.
Conventions
- Une image par version majeure, construite par le même Dockerfile avec
PG_VERSION. Rien n'y est propre à une version : ce qui en dépend se lit dansPG_MAJOR, fourni par l'image de base. - Versions épinglées dans le Dockerfile
(0003) :
TIMESCALEDB_VERSION,TIMESCALEDB_VERSION_PG15(0007) etVCHORD_VERSION. Les changer suit la procédure de docs/exploitation/publication.md, et met à jour le tableau et les badges duREADME.md. - Le reste vient d'apt, à jour (0002) : PostgreSQL, pgvector, PostGIS, Debian. Aucune version de paquet n'est écrite dans le Dockerfile, sauf les en-têtes du serveur, épinglés sur la version du serveur installé.
- Nouvelle extension : l'installer dans l'étape finale du Dockerfile, l'ajouter à
init-extensions.sh, à la liste contrôlée partests/test-1-config.sql, lui écrire untests/test-N-nom.sql, et l'ajouter aux deux fichierstests/reprise-*.sql. - Nouvelle version majeure de PostgreSQL : l'ajouter à la matrice de la CI, au tableau
et au badge du
README.md, et vérifier le point de montage du volume (docs/architecture.md). - Tests SQL : chaque fichier commence par
\set ON_ERROR_STOP onet lève une exception quand un contrôle échoue. Ils ne supposent ni l'utilisateur ni la basepostgres. - CI sans action externe (0004) : des
commandes
gitetdocker, jamais deuses:. - Commentaires : en français. Le « pourquoi » local reste à côté du code. Les tests SQL
tests/test-*.sqlet les scripts de démarrage sont encore commentés en anglais : on les traduit quand on les modifie.
Pièges connus
- Changer la version de TimescaleDB rend une base existante inutilisable jusqu'à sa mise
à niveau. L'image ne contient que la bibliothèque de sa version : toute requête échoue
avec
could not access file "$libdir/timescaledb-X.Y.Z"tant queALTER EXTENSION timescaledb UPDATEn'a pas été exécuté, en première instruction d'une sessionpsql -X.pg_isreadyrépond pourtant, et le conteneur paraît sain. - Des en-têtes plus récents que le serveur cassent TimescaleDB au chargement
(
undefined symbol: palloc0_mul), sans erreur à la compilation. C'est ce qui arrive si l'on installepostgresql-server-devsans mettre le serveur à niveau. - La couche
apt-get upgradeest mise en cache comme les autres. Une construction locale ne reprend les mises à jour qu'avec un nouvelAPT_REFRESH. PG_VERSIONa deux sens. Avant le premierFROM, c'est l'argument de construction (18). Dans les étapes, c'est la variable d'environnement de l'image de base, la version du paquet au moment où TensorChord l'a construite (18.3-1.pgdg12+1). Elle reste telle quelle dans l'image publiée, alors que le serveur est mis à niveau : la version du serveur se lit parpostgres --version.- Le point de montage du volume change avec PostgreSQL 18
(docs/architecture.md). Jusqu'à 17, un volume monté sur
/var/lib/postgresqlreste vide : les données partent dans un volume anonyme. init-extensions.shne s'exécute qu'à l'initialisation d'un volume vide. Une extension ajoutée à l'image n'apparaît pas dans une base existante : il faut l'y créer à la main.- Remplacer la commande du conteneur remplace
shared_preload_libraries. Sanstimescaledb,vchord, les deux extensions ne se chargent pas. - L'enveloppe du point d'entrée parcourt tout le volume à chaque démarrage
(
chown -R) : le démarrage s'allonge avec le nombre de fichiers de la base. - Le serveur temporaire de l'initialisation répond déjà aux requêtes, par le socket,
avant que les extensions soient créées. Un test qui attend seulement une réponse démarre
trop tôt :
tests.shattend aussiPostgreSQL init process completedans le journal. docker logs … | grep -qéchoue souspipefailalors que le motif est trouvé :grep -qferme le tube à la première correspondance.tests.shlit le journal en entier avant de chercher.- Une exécution nocturne qui échoue aux tests ne publie rien et recompile la nuit
suivante : la clé
APT_REFRESHn'est gardée que par l'image publiée. - Chaque reconstruction déclenchée par apt recompile TimescaleDB : l'étape de compilation part de l'étape mise à niveau.
Git
- Messages de commit en français. Jamais de trailer
Co-Authored-By. - Ne pas pousser sans demande explicite : un push sur
mainrepublie les quatre images, dontlatest, que d'autres projets utilisent comme base de données. - En cas d'échec de push : retenter. Après deux échecs rapprochés, parler d'indisponibilité probablement temporaire de Gitea, sans mettre en cause les identifiants.
Documentation
README.md: la vitrine du dépôt. Il résume et renvoie, le détail vit ici et dansdocs/.CLAUDE.md: commandes, conventions, pièges connus.docs/architecture.md: étapes de construction, démarrage, données.docs/exploitation/: CI, mises à jour, changement de version.docs/decisions/: décisions numérotées et figées.docs/a-faire.md: points ouverts.
Règles :
- Un fait, un seul endroit. Ailleurs, un lien, jamais une copie.
- La doc décrit le présent. Pas de dates, de « corrigé le », ni de récit. L'historique va dans les messages de commit, le « pourquoi » d'un choix dans une décision.
- Une décision est numérotée et figée (
0001-titre.md). On ne la modifie pas : une nouvelle décision la remplace et le dit. a-faire.mdne contient que l'ouvert. Un point terminé est supprimé, pas coché.- La doc est mise à jour dans le même commit que le code qu'elle décrit. Sinon, la tâche n'est pas terminée.
- Un commentaire cite un document par son nom de fichier, jamais par un numéro de section.
- Un fichier au-delà de ~300 lignes se découpe.