---
tags: [Infra]
description: "Site Astro statique en ligne : webhook Forgejo HMAC, build puis miroir SFTP."
nature: documentation
projects:
  - [[03_PROJETS/VPS-IA]]
type: note
---
# Site Shizen — Astro + déploiement automatique

#VPS #site #astro #deploiement #forgejo

**Date** : 2026-11-07 · **Cible** : https://site.shizendo.ovh (app YunoHost `my_webapp`)

## État

- Site **Astro** statique en ligne (4 pages : accueil, à-propos, contact, 404 + erreurs 403/404).
- L'ancien site **MkDocs** et son pipeline **PHP/Python** ont été supprimés (48 fichiers purgés du docroot, clone `/home/shizendo/dev/shizendo-site` + venv 158 Mo retirés).
- Nettoyé aussi : webhook `www/scripts/deploy-mkdocs.php`, `sftp_sync.py`, `deploy-mkdocs.sh`.

## Chaîne de déploiement

```
push Forgejo shizendo/shizendo-site (branche main)
  → webhook Forgejo (POST http://127.0.0.1:8787/deploy, signature HMAC)
  → ~/.opencode/bin/webhook-listener.mjs   (valide HMAC, verrou anti-doublon, filtre le dépôt)
  → ~/.opencode/bin/deploy-site.sh         (git fetch --ff-only, npm install, astro build)
  → ~/.opencode/bin/sftp-mirror.sh         (miroir dist/ → /www/ via SFTP, manifest local)
  → site en ligne
```

## Emplacements

| Élément | Chemin |
|---|---|
| Source du site (git) | `/var/lib/opencode/projects/site-shizendo` → Forgejo `shizendo/shizendo-site` (deploy key en écriture) |
| Scripts de service | `~/.opencode/bin/{deploy-site.sh,sftp-mirror.sh,webhook-listener.mjs,webhook-listener.sh,mywebapp-askpass.sh}` |
| Journaux / manifest | `~/.local/state/site-deploy/{deploy.log,webhook.log,manifest-_www.txt}` |
| Garde du listener | cron `* * * * * /usr/bin/flock -n .../listener.lock .../webhook-listener.sh` (pas de systemd user : opencode n'a ni linger ni user unit) |
| Doc YunoHost erreurs | `/var/www/my_webapp/www/error/{403,404}.html` (source : `public/error/`) |

## Accès

- **SFTP** : `my_webapp@site.shizendo.ovh:222` (le port SSH est 222, pas 22) — mot de passe dans `pass` `opencode/mywebapp-sftp`, lu à l'exécution via `mywebapp-askpass.sh`.
- **Secret webhook** : `pass` `opencode/site-webhook-secret` (même valeur que dans la config Forgejo).
- Santé du listener : `curl http://127.0.0.1:8787/health` → `ok` / `busy`.
- Déclenchement manuel : `~/.opencode/bin/deploy-site.sh` (`SKIP_GIT=1` pour bâtir l'arbre courant).

## Pièges rencontrés

- `my_webapp` est **seul** dans le groupe `sftp.app` → `ForceCommand internal-sftp` + `ChrootDirectory %h` : **aucun shell distant, rsync impossible** → miroir maison par batch sftp.
- `sftp -b` désactive côté client la méthode ``password`` → piloter sftp **sans -b**, en pipant les commandes dans stdin (`setsid` + `SSH_ASKPASS_REQUIRE=force`).
- `[[ -s /dev/fd/N ]]` est **toujours faux** sur un process substitution (pipe) → les diffs renvoyaient vide ; utiliser de vrais fichiers temporaires.
- **Forgejo** : `webhook.ALLOWED_HOST_LIST` vaut `external` par défaut → **refuse 127.0.0.1** ; corrigé en `external,loopback` dans `/var/www/forgejo/custom/conf/app.ini` + `systemctl restart forgejo`.
- Le docroot doit appartenir à `my_webapp` : l'ancien pipeline faisait `chown -R shizendo:shizendo` sur `www`, ce qui **cassait l'écriture SFTP**.
- Un webhook se place sur le **bon** dépôt (le premier était resté sur `shizendo/vps-opencode`).
- `pkill -f` avec un motif dans sa propre ligne de commande = self-kill (utiliser le déguisement `[w]ebhook`).

## Suivi et améliorations

- 2026-11-07 : mise en place complète (projet Astro, miroir SFTP, listener webhook, purge MkDocs).
- À venir : contenu des pages à-compléter, éventuel sitemap (`@astrojs/sitemap`), règle sudoers `my_webapp` dans `/etc/sudoers` devenue inerte à purger.