Enclume : editeur CLAPI, catalogue de 26 packs, empaquetage Docker
This commit is contained in:
1 parent
aa71251de0
commit
de7a691861
59 files changed
+4466
-205
No files matched your search
@@ -0,0 +1,91 @@
|
||||
# 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
|
||||
|
||||
```bash
|
||||
git clone https://gitea.tips-of-mine.com/hubert/enclume.git
|
||||
cd enclume
|
||||
cp .env.example .env # renseigner ENCLUME_TAG, ENCLUME_DOMAINE, POSTGRES_PASSWORD
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
curl -s https://clapi.tips-of-mine.com/sante
|
||||
```
|
||||
|
||||
`/sante` 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.
|
||||
|
||||
```bash
|
||||
sed -i 's/^ENCLUME_TAG=.*/ENCLUME_TAG=1.4.0/' .env
|
||||
docker compose pull && docker compose up -d
|
||||
curl -s https://clapi.tips-of-mine.com/sante | grep 1.4.0
|
||||
```
|
||||
|
||||
## Retour arrière
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
1. **Aucun `latest` en production.** Le compose refuse de démarrer si `ENCLUME_TAG` est absent.
|
||||
2. **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.
|
||||
3. **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 :
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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.
|
||||
@@ -0,0 +1,86 @@
|
||||
# Création des emplacements — Gitea et Harbor
|
||||
|
||||
À faire une seule fois, avant le premier `git push`. Les valeurs ci-dessous sont celles
|
||||
qu'attendent `compose.yaml` et `.gitea/workflows/build.yaml`.
|
||||
|
||||
## Gitea
|
||||
|
||||
**Deux dépôts, pas un.**
|
||||
|
||||
| Dépôt | Contenu | Visibilité |
|
||||
|---|---|---|
|
||||
| `enclume` | l'application, les images, la CI | public |
|
||||
| `enclume-catalogue` | uniquement `catalog/`, les packs YAML | public |
|
||||
|
||||
Le catalogue vit à part parce que `catalog-sync` le tire directement : ajouter un pack devient
|
||||
un commit, sans reconstruction d'image. C'est aussi ce qui rendra les contributions par pull
|
||||
request lisibles — on relit dix lignes de YAML, pas un diff mêlé au code.
|
||||
|
||||
Sur `enclume` :
|
||||
|
||||
- branche par défaut `main`, protégée : pas de push direct, fusion par pull request
|
||||
- Actions activées, avec un runner ayant accès au démon Docker
|
||||
- secrets du dépôt : `HARBOR_USER` et `HARBOR_TOKEN` (le compte robot créé plus bas)
|
||||
- licence MIT à la racine
|
||||
|
||||
Sur `enclume-catalogue` : même protection de branche. C'est là qu'arriveront les soumissions
|
||||
modérées du chantier 5.
|
||||
|
||||
## Harbor
|
||||
|
||||
Projet **`enclume`**, en accès **public** : n'importe qui peut alors tirer les images pour
|
||||
s'auto-héberger, sans compte chez toi. Seule la publication demande une authentification.
|
||||
|
||||
Dépôts créés automatiquement au premier push : `enclume/web` et `enclume/catalog-sync`.
|
||||
|
||||
### Compte robot
|
||||
|
||||
Créer un robot au niveau du projet, nommé `robot$enclume-ci`, avec les droits
|
||||
**push** et **pull** sur les dépôts — rien d'autre, pas de suppression. Le secret généré
|
||||
va dans `HARBOR_TOKEN` côté Gitea, le nom complet du robot dans `HARBOR_USER`.
|
||||
|
||||
### Immuabilité des versions
|
||||
|
||||
Règle d'immuabilité sur les tags correspondant à `[0-9]*.[0-9]*.[0-9]*`.
|
||||
|
||||
C'est le réglage qui donne sa valeur au retour arrière : une version publiée ne peut plus
|
||||
être écrasée, donc `ENCLUME_TAG=1.3.2` désigne aujourd'hui exactement la même image
|
||||
qu'au jour de sa publication.
|
||||
|
||||
### Rétention
|
||||
|
||||
Conserver les **10 derniers tags** correspondant à `[0-9]*.[0-9]*.[0-9]*`, et purger les tags
|
||||
`0.0.0-main.*` de plus de 30 jours. Les tags `sha-*` servent au diagnostic, une rétention de
|
||||
30 jours suffit.
|
||||
|
||||
### Analyse
|
||||
|
||||
Scanner automatiquement à la publication. Ne pas activer « empêcher le déploiement d'images
|
||||
vulnérables » au démarrage : une CVE sans correctif dans une image de base bloquerait un
|
||||
déploiement urgent. Le rapport Trivy dans la CI suffit à surveiller.
|
||||
|
||||
## Enchaînement
|
||||
|
||||
```bash
|
||||
git remote add origin https://gitea.tips-of-mine.com/hubert/enclume.git
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
La CI construit, teste et publie `0.0.0-main.<commit>`. Pour une vraie version :
|
||||
|
||||
```bash
|
||||
git tag v1.0.0 && git push origin v1.0.0
|
||||
```
|
||||
|
||||
Puis sur le serveur, dans le répertoire du compose :
|
||||
|
||||
```bash
|
||||
cp .env.example .env # renseigner ENCLUME_TAG=1.0.0 et le domaine
|
||||
docker compose pull && docker compose up -d
|
||||
curl -s https://<domaine>/sante
|
||||
```
|
||||
|
||||
## Réseau Traefik
|
||||
|
||||
Le compose attend un réseau externe nommé `traefik`. S'il porte un autre nom dans ton
|
||||
installation, ajuster la section `networks` et l'étiquette `traefik.docker.network`.
|
||||
Reference in new issue
Block a user