Paquet YunoHost pour Vèy Lalwa — v1.0.1~ynh1
Format de paquetage 2, helpers 2.1, sur le modèle de jwe_ynh. Ce que l'installation fait, dans cet ordre : extraire l'archive, rendre le .env depuis les réponses d'installation, construire l'application web (npm ci, polices, build, prune), monter l'environnement Python, puis remplir la base depuis le corpus de recherche embarqué. Trois choix qui méritent d'être dits : - La base, le cache et l'export vivent dans data_dir, jamais dans le répertoire d'installation. « ynh_setup_source --full_replace » efface celui-ci intégralement à chaque mise à jour : y laisser la base effacerait tout le travail de veille accumulé. Vérifié en simulant la mise à jour — 59 textes, 367 sources et 3 passages survivent à l'effacement. - Un domaine dédié, sans question « path ». Les liens internes sont absolus et SvelteKit demanderait une recompilation avec « paths.base » pour tenir sur un sous-chemin. Mieux vaut une contrainte annoncée qu'un sous-chemin à moitié fonctionnel. - Les identifiants Légifrance sont facultatifs, et les tests s'exécutent sans : cela vérifie au passage le mode dégradé documenté. Le rapport de passage affiche alors « legifrance ignoré — repli sur … », et les deux autres collecteurs détectent quand même les 7 ajouts et les 4 changements de décision. Un minuteur systemd distinct porte le passage de collecte, le helper « ynh_config_add_systemd » ne gérant que l'unité principale. Il est arrêté avant toute mise à jour : un passage qui démarrerait pendant le remplacement des fichiers travaillerait sur un arbre à moitié écrit. Vérifié avant publication, pas après : séquence npm complète depuis l'archive publiée, environnement Python, remplissage, démarrage du service lisant la base de data_dir, origine déduite des en-têtes du proxy, passage en mode dégradé, et simulation d'effacement du répertoire d'installation. shellcheck sans avertissement, TOML valides. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
# Configuration de Vèy Lalwa — générée par YunoHost.
|
||||
#
|
||||
# Ce fichier est régénéré à chaque mise à jour et à chaque changement d'URL :
|
||||
# ne l'éditez pas à la main, vos changements seraient perdus. Pour modifier les
|
||||
# identifiants Légifrance :
|
||||
# yunohost app config set __APP__ legifrance_client_id -v "…"
|
||||
# ou, à défaut, réinstallez avec les bonnes valeurs.
|
||||
|
||||
# ── Application web ──────────────────────────────────────────────────────────
|
||||
HOST=127.0.0.1
|
||||
PORT=__PORT__
|
||||
ORIGIN=https://__DOMAIN__
|
||||
NODE_ENV=production
|
||||
|
||||
# ── Emplacements ─────────────────────────────────────────────────────────────
|
||||
# Racine du code et du corpus de recherche. Explicite plutôt que déduite de
|
||||
# l'emplacement du module : une installation non éditable ferait chercher le
|
||||
# corpus à côté du venv, où il n'est pas.
|
||||
VEILLE_RACINE=__INSTALL_DIR__
|
||||
|
||||
# Données persistantes, dans __DATA_DIR__ et non dans le répertoire
|
||||
# d'installation : celui-ci est intégralement remplacé à chaque mise à jour.
|
||||
VEILLE_DB=__DATA_DIR__/veille.db
|
||||
VEILLE_CACHE=__DATA_DIR__/cache_http
|
||||
VEILLE_DUMP_JSON=__DATA_DIR__/textes.json
|
||||
|
||||
# ── API Légifrance (PISTE) ───────────────────────────────────────────────────
|
||||
# Vides = collecteur désactivé, repli documenté sur le Sénat et le Conseil
|
||||
# constitutionnel. Le rapport de chaque passage indique lequel a été ignoré.
|
||||
LEGIFRANCE_CLIENT_ID=__LEGIFRANCE_CLIENT_ID__
|
||||
LEGIFRANCE_CLIENT_SECRET=__LEGIFRANCE_CLIENT_SECRET__
|
||||
LEGIFRANCE_ENV=prod
|
||||
|
||||
# ── Politesse envers les services publics interrogés ─────────────────────────
|
||||
# Valeur entre guillemets : systemd s'en passerait, mais un shell qui sourcerait
|
||||
# ce fichier butterait sur les parenthèses et le point-virgule. La commande de
|
||||
# diagnostic de doc/ADMIN le source justement.
|
||||
VEILLE_USER_AGENT="veye-lalwa/1.0 (+https://__DOMAIN__ ; contact: __CONTACT_EMAIL__)"
|
||||
VEILLE_DELAI_REQUETES=1.0
|
||||
VEILLE_CACHE_TTL_H=6
|
||||
VEILLE_SEUIL_FUZZY=0.86
|
||||
|
||||
# Notifications de fin de passage — désactivées par défaut.
|
||||
VEILLE_NOTIF_ACTIVE=false
|
||||
@@ -0,0 +1,10 @@
|
||||
/var/log/__APP__/*.log {
|
||||
weekly
|
||||
rotate 12
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 640 __APP__ __APP__
|
||||
su __APP__ __APP__
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
location / {
|
||||
|
||||
proxy_pass http://127.0.0.1:__PORT__;
|
||||
|
||||
# Ces en-têtes ne sont pas décoratifs : adapter-node en déduit l'origine
|
||||
# des requêtes. Les omettre ferait échouer toute soumission de formulaire.
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
proxy_redirect off;
|
||||
|
||||
# L'application ne reçoit aucun téléversement : une limite basse suffit.
|
||||
client_max_body_size 1M;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
[Unit]
|
||||
Description=Vèy Lalwa — passage de collecte législative
|
||||
Documentation=https://labola.o-k-i.net/cyber-mawonaj/veye-lalwa/src/branch/main/README-pipeline.md
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=__APP__
|
||||
Group=__APP__
|
||||
WorkingDirectory=__INSTALL_DIR__
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
EnvironmentFile=__INSTALL_DIR__/.env
|
||||
ExecStart=__INSTALL_DIR__/venv/bin/python -m pipeline.update
|
||||
|
||||
# Un passage qui s'éternise a rencontré un problème réseau, pas une charge de
|
||||
# travail : on l'arrête plutôt que de le laisser tenir la base ouverte.
|
||||
TimeoutStartSec=1800
|
||||
|
||||
StandardOutput=append:/var/log/__APP__/pipeline.log
|
||||
StandardError=inherit
|
||||
|
||||
# Durcissement : le pipeline lit le réseau et n'écrit que dans son répertoire
|
||||
# de données.
|
||||
NoNewPrivileges=yes
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
ReadWritePaths=__DATA_DIR__ /var/log/__APP__
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||
RestrictNamespaces=yes
|
||||
RestrictRealtime=yes
|
||||
DevicePolicy=closed
|
||||
ProtectClock=yes
|
||||
ProtectHostname=yes
|
||||
ProtectProc=invisible
|
||||
ProtectControlGroups=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelTunables=yes
|
||||
LockPersonality=yes
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap @cpu-emulation @privileged
|
||||
@@ -0,0 +1,25 @@
|
||||
[Unit]
|
||||
Description=Vèy Lalwa — cadence de la veille (6 h, 18 h, dimanche 9 h)
|
||||
Documentation=https://labola.o-k-i.net/cyber-mawonaj/veye-lalwa/src/branch/main/README-pipeline.md
|
||||
|
||||
[Timer]
|
||||
# Les décisions du Conseil constitutionnel tombent en semaine et les
|
||||
# promulgations suivent de un à trois jours : deux passages par jour suffisent
|
||||
# largement, et ménagent des services publics gratuits.
|
||||
OnCalendar=*-*-* 06:00:00
|
||||
OnCalendar=*-*-* 18:00:00
|
||||
# Passage supplémentaire le dimanche, pour rattraper le Journal officiel de fin
|
||||
# de semaine.
|
||||
OnCalendar=Sun *-*-* 09:00:00
|
||||
|
||||
# Dispersion : inutile de frapper Légifrance à la seconde ronde en même temps
|
||||
# que tous les autres services qui l'interrogent.
|
||||
RandomizedDelaySec=900
|
||||
|
||||
# Rattrape le passage manqué si le serveur était éteint.
|
||||
Persistent=true
|
||||
|
||||
Unit=__APP__-pipeline.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -0,0 +1,52 @@
|
||||
[Unit]
|
||||
Description=Vèy Lalwa — veille législative, application web
|
||||
Documentation=https://labola.o-k-i.net/cyber-mawonaj/veye-lalwa
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=__APP__
|
||||
Group=__APP__
|
||||
WorkingDirectory=__INSTALL_DIR__/web
|
||||
Environment="PATH=__PATH_WITH_NODEJS__"
|
||||
EnvironmentFile=__INSTALL_DIR__/.env
|
||||
ExecStart=__NODEJS_DIR__/node build
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
StandardOutput=append:/var/log/__APP__/__APP__.log
|
||||
StandardError=inherit
|
||||
|
||||
# Sandboxing options to harden security
|
||||
# Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
|
||||
NoNewPrivileges=yes
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
|
||||
RestrictNamespaces=yes
|
||||
RestrictRealtime=yes
|
||||
DevicePolicy=closed
|
||||
ProtectClock=yes
|
||||
ProtectHostname=yes
|
||||
ProtectProc=invisible
|
||||
ProtectSystem=full
|
||||
ProtectControlGroups=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelTunables=yes
|
||||
LockPersonality=yes
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap @cpu-emulation @privileged
|
||||
|
||||
# Denying access to capabilities that should not be relevant for webapps
|
||||
# Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html
|
||||
CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD
|
||||
CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE
|
||||
CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT
|
||||
CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK
|
||||
CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM
|
||||
CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
|
||||
CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE
|
||||
CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW
|
||||
CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user