feat(gitea): script d'installation LXC Alpine + README #19
Notifications
Due Date
No due date set.
Blocks
Depends on
#21 feat(proxy): jail fail2ban gitea + rate-limit et fermeture de /metrics
Damien/infra-scripts
#22 fix(gitea-runner): URL d'instance complète et procédure de ré-enregistrement
Damien/infra-scripts
#18 feat(lib): helper ini_set idempotent pour merge de fichiers INI
Damien/infra-scripts
Reference: Damien/infra-scripts#19
Reference in New Issue
Block a user
Objectif
Nouveau script
gitea/install.shsur le modèle d'openbao/install.sh: point d'entrée unique, trois modes auto-détectés (hôte Proxmox → création LXC, hôte Proxmox + conteneur existant → update, dans le LXC → install ou update), plus les flags--install/--updatepour le pipe viapct exec.Remplace le déploiement actuel via community-scripts. La migration des données de l'instance existante est hors périmètre : cette issue produit une instance neuve.
Décision structurante :
apk, pas de binaire téléchargéContrairement à
openbao/install.shetgitea-runner/install.shqui téléchargent une release GitHub, Gitea passe par le gestionnaire de paquets Alpine.Raison : les binaires officiels de
dl.gitea.comembarquent SQLite via CGO et sont liés à la glibc. Sur musl, c'est un pari (gcompat+ erreurslibc.so.6: version GLIBC_2.x not found). Alpine package Gitea nativement en community, build musl, avec un sous-paquetgitea-openrc.Conséquences sur le pattern habituel :
apk add gitea gitea-openrcapk upgrade gitea/opt/*_version.txtapk info -v giteaLe mode
--updatese réduit donc quasiment àrefresh_os_packages+apk upgrade gitea. Pas de/opt/gitea_version.txt.Vérifier au premier run que
giteaest disponible encommunitysur la version d'Alpine sélectionnée pardetect_latest_alpine_template()(3.22 au moment de la rédaction) et pas seulement suredge. Si absent en stable : échouer bruyamment avec un message explicite plutôt que de taggeredge/community, qui n'a pas sa place sur une instance de production.Configuration
app.iniPilotée exclusivement par
ini_set()(cf. #18), jamais par un heredoc écrasant. Le script est propriétaire des clés listées ci-dessous et ne touche à rien d'autre.Points critiques :
ROOT_URLest l'URL publique, pas l'URL tailnet. Elle alimente les URL de clone affichées, les webhooks et les redirections. Ne pas y mettregitea.taila5ad8.ts.netpar réflexe « loopback first » :HTTP_ADDR(interne) etROOT_URL(publique) sont deux choses distinctes.DISABLE_SSH = true: usage exclusivement HTTPS confirmé, pas de serveur SSH interne à exposer.COLORIZE = false: les codes ANSI cassent le<HOST>du filtre fail2ban de #21.INSTALL_LOCK = trueavant le premier démarrage du service. Sinon l'assistant d'installation web est exposé surgitea.arnodo.fret le premier arrivé devient admin.REVERSE_PROXY_TRUSTED_PROXIESne doit jamais valoir*(cf. CVE-2026-20896 sur les images Docker).REVERSE_PROXY_LIMIT = 2est une hypothèse (Traefik +tailscale serve) à valider empiriquement — voir la procédure ci-dessous.Token metrics
Génération conditionnelle : si
[metrics] TOKENest déjà renseigné, ne pas y toucher — un rejeu qui régénère le token casse le scrape Prometheus. Sinonopenssl rand -hex 32, écrit viaini_set, et affiché en fin d'install pour report manuel.Surchargeable par
GITEA_METRICS_TOKEN. La configuration Prometheus est hors périmètre.Création de l'admin
Après
INSTALL_LOCK = trueet avant l'annonce de fin, en non-interactif :Idempotent : ne rien faire si un compte admin existe déjà. Mot de passe généré si
GITEA_ADMIN_PASSWORDest absent, affiché une seule fois en sortie.Exposition réseau
Loopback +
tailscale serve --bg --https=443 http://127.0.0.1:3000, comme OpenBao. Gitea devient joignable surhttps://gitea.taila5ad8.ts.net— sans port, ce qui casse les consommateurs actuels pointant sur:3000(traités dans #21 et #22).Réutiliser la logique de
configure_tailscale_proxy()d'openbao/install.sh: gestion duBackendState,TS_AUTHKEYoptionnel avec repli sur instruction manuelle,tailscale serveidempotent.Client rsyslog
Installer et configurer un forward de
/var/log/gitea/gitea.logvers le proxy en TCP, via le moduleimfilede rsyslog, avec un tag identifiant le service. Le récepteur est traité en #20. Adresse du proxy surchargeable parSYSLOG_TARGET.Choix de
rsyslogplutôt que le sous-loggerMODE = connnatif de Gitea : découplé, non bloquant (un logger réseau bloquant peut stall Gitea), et indépendant des changements de syntaxe des sous-loggers intervenus en 1.21.Reste du script
nesting=1, passthrough/dev/net/tun,--onboot 1, tagsinfra-script,giteaCORES=2,RAM=2048,DISK=16,LXC_TAG=gitea,GITEA_HOSTNAME=gitea/var/log/gitea/gitea.log(daily, rotate 7, compress, copytruncate)enable_tty1_autologin/etc/profile.d/00-gitea.sh, heredoc quoté, état calculé au login : FQDN tailnet, version (apk info -v gitea), état du service, URL publiquelib/common.shavec le gardedeclare -Fgitea/README.mdSur le modèle de
openbao/README.md: tableau des modes, tableau des variables d'environnement, architecture. Plus deux sections spécifiques :Ordre de déploiement — non négociable
L'ordre doit être documenté explicitement, avec l'avertissement suivant :
Séquence : #18 → #19 → validation XFF → #20 → #21 → #22.
Procédure de validation XFF
Depuis une IP externe connue (partage de connexion mobile), provoquer un login raté, puis dans le LXC :
100.x.x.xREVERSE_PROXY_LIMIT127.0.0.1tailscale servemasque tout127.0.0.0/8est dans les trusted proxiesTant que cette ligne n'affiche pas l'IP réelle, #21 reste non déployée.
Fichiers touchés
gitea/install.sh(nouveau)gitea/README.md(nouveau)README.mdracine — ligne dans le tableau « Available Scripts »Critères d'acceptation
app.inihors périmètre modifiée, token metrics inchangé[security]: la clé est restauréecurl -H "Authorization: Bearer $TOKEN" https://gitea.<tailnet>.ts.net/metricsrenvoie les métriquesDépendances
ini_set)