4.1 KiB
Exploitation
Composants
| Conteneur | Image | Rôle | État |
|---|---|---|---|
web |
harbor…/enclume/web:<version> |
l'application : éditeur, validation, génération | sans état |
catalog-sync |
harbor…/enclume/catalog-sync:<version> |
clone le dépôt du catalogue dans un volume, prévient l'application | sans état |
db |
postgres:16.4-alpine |
partages et projets enregistrés (à partir du chantier 2) | volume donnees |
Traefik, Authentik et le tunnel Cloudflare sont ceux du homelab : ils ne font pas partie
de cette pile. web rejoint le réseau traefik existant et n'expose aucun port.
Le réseau interne est marqué internal: true : db et catalog-sync n'ont aucun accès
sortant depuis Docker, et personne ne les joint de l'extérieur.
Première installation
git clone https://gitea.tips-of-mine.com/Tips-Of-Mine/Enclume.git
cd Enclume
cp .env.example .env # renseigner ENCLUME_TAG, ENCLUME_DOMAINE, POSTGRES_PASSWORD, ENCLUME_SECRET_KEY
docker compose pull
docker compose up -d
curl -s https://enclume.tips-of-mine.com/health
/health renvoie la version et le commit de l'image en cours : c'est la source de vérité
sur ce qui tourne réellement.
Mise à jour
Une évolution donne une image, jamais un docker compose build sur le serveur.
sed -i 's/^ENCLUME_TAG=.*/ENCLUME_TAG=1.4.0/' .env
docker compose pull && docker compose up -d
curl -s https://enclume.tips-of-mine.com/health | grep 1.1.4
Retour arrière
sed -i 's/^ENCLUME_TAG=.*/ENCLUME_TAG=1.3.2/' .env
docker compose up -d web catalog-sync
Quelques secondes, sans reconstruction. Trois conditions le garantissent :
- Aucun
latesten production. Le compose refuse de démarrer siENCLUME_TAGest absent. - Aucun état dans
web. Le système de fichiers est en lecture seule, le projet vit dans le navigateur du visiteur. Revenir en arrière ne perd rien. - Migrations compatibles dans les deux sens. À partir du chantier 2 : on ajoute une colonne, on ne la supprime jamais dans la même version que le code qui cesse de l'utiliser. La suppression arrive une version plus tard, quand le retour arrière n'est plus envisagé. Sans cette règle, revenir à l'image précédente casse l'application.
Conserver au minimum les trois dernières versions dans Harbor (politique de rétention par nombre de tags, pas par date).
Catalogue
catalog-sync clone le dépôt du catalogue toutes les cinq minutes, publie le contenu de
façon atomique dans le volume partagé, puis appelle /recharger. Ajouter un pack ne demande
donc ni image ni redémarrage : un commit suffit.
Si CATALOG_REPO est vide, l'application utilise le catalogue livré dans son image.
Sauvegarde
Le volume catalogue est jetable, il se reconstruit depuis Git. Seul donnees compte :
docker compose exec -T db pg_dump -U enclume enclume | zstd > enclume-$(date +%F).sql.zst
À brancher sur la sauvegarde existante du homelab.
Journaux et diagnostic
docker compose logs -f web
docker compose exec web python -m enclume.cli --list # le catalogue vu par l'application
docker compose ps # état des healthchecks
Ce qui est verrouillé dans web
Utilisateur non root (uid 10001), racine en lecture seule, /tmp en tmpfs, toutes les
capacités retirées, no-new-privileges, corps de requête plafonné à 2 Mo, en-têtes CSP,
nosniff et no-referrer posés par l'application, limitation de débit au niveau de Traefik.
Le registre et le tunnel
Le runner Gitea et Harbor sont sur le meme reseau. Faire sortir les couches d'images par le
tunnel Cloudflare pour revenir chez soi n'a pas d'interet, et le plan gratuit plafonne les
corps de requete a 100 Mo : une couche plus grosse est coupee net, avec un 413 Payload Too Large en pleine publication.
La resolution interne evite le probleme. Sur l'hote du runner, dans le compose du runner :
extra_hosts:
- "registry.tips-of-mine.com:<ip-locale-de-harbor>"
Le nom reste identique, donc les tags des images ne changent pas et le certificat reste valide. Seul le chemin reseau change.