Aller au contenu

ADR 0008 — Déploiement IONOS mutualisé via SFTP + GitHub Actions

Contexte

La vague V1 a posé la living documentation (MkDocs Material) mais laissé le déploiement en non-objectif explicite (voir ADR 0007, section "Non-objectifs de cette vague"). La V5 lève ce report.

Hypothèse initiale de la reprise : un VPS Linux L IONOS avec SSH root, permettant d'installer Caddy + rsync atomique. Cette hypothèse a été invalidée en inspectant le projet voisin kanban-vibe, déployé depuis plusieurs mois sur aelworks.fr via une stack radicalement différente.

Contraintes effectives :

  1. Infra existante sur aelworks.fr : hébergement mutualisé IONOS (pas un VPS). Pas d'accès SSH au serveur, pas d'install possible de reverse-proxy, pas de systemd.
  2. Cohérence multi-projets : au moins un autre projet (kanban-vibe) déploie déjà sur aelworks.fr. Avoir deux stacks différentes pour un même domaine = dette opérationnelle et cognitive.
  3. Site statique : mkdocs build produit site/ — pas de backend, pas de runtime. N'importe quel serveur de fichiers statiques suffit.
  4. Workflow solo direct-to-main : pas de flux de PR en V5, pas de besoin de preview deploys.

Options envisagées

  1. VPS Linux IONOS + Caddy + rsync (plan initial V5) — maîtrise totale du serveur, TLS Let's Encrypt, rollback atomique. Rejeté : pas d'infra VPS provisionnée, scope hors-budget, divergence avec kanban-vibe.
  2. IONOS mutualisé + SFTP manuel local (npm run deploy) — push manuel, pas de CI en V5. Rejeté : incohérent avec la CI déjà en place sur kanban-vibe, un déploiement manuel se saute plus facilement qu'un workflow qui tourne seul.
  3. IONOS mutualisé + SFTP via GitHub Actions (aligné kanban-vibe) — build reproductible en CI, secrets GitHub, zéro action locale nécessaire. Retenu.
  4. Cloudflare Pages / Vercel / GitHub Pages — providers tiers. Rejeté : ajouterait un 2e point de déploiement pour un bénéfice faible en solo direct-to-main (pas de preview PR à héberger).

Décision

Retenue : IONOS mutualisé + SFTP via GitHub Actions, modèle identique au workflow kanban-vibe/.github/workflows/ci-cd.yml.

Le workflow .github/workflows/deploy-docs.yml :

  • Trigger : push sur main (filtré par chemins) et workflow_dispatch (re-jouer sans commit).
  • Job build : Ubuntu + Node 20 + Python 3.12 → npm run docs:build → artefact site/.
  • Job deploy : download artefact → upload SFTP via Dylan700/sftp-upload-action@latest → racine webroot (./).
  • concurrency.group: deploy-docs pour sérialiser les déploiements concurrents.
  • fetch-depth: 0 au checkout, requis par mkdocs-git-revision-date-localized-plugin.

Secrets GitHub à provisionner manuellement dans les settings du repo :

  • SDEG_SFTP_SERVER — hostname IONOS du sous-domaine sdeg.aelworks.fr.
  • SDEG_SFTP_USERNAME — user SFTP dédié à ce sous-domaine.
  • SDEG_SFTP_PASSWORD — mot de passe SFTP dédié.

Conséquences

Positives :

  • Cohérence aelworks.fr : même stack que kanban-vibe, onboarding d'un futur projet = copier un workflow.
  • Build reproductible : la CI est la source de vérité. Pas de "il a construit depuis sa machine".
  • Zéro infra à gérer : pas de VPS, pas de certificats, pas de firewall. IONOS gère tout ce qui est serveur.
  • Rollback simple : git revert + push main re-déploie l'état précédent.
  • Secrets isolés : les credentials SFTP vivent dans GitHub secrets, jamais dans le repo.

Négatives :

  • Pas d'atomic swap : un upload SFTP n'est pas atomique. Pendant les secondes d'upload, le site peut servir un mélange ancien/nouveau. Mitigation : la doc statique est lisible même partielle, et les déploiements sont rares (commits doc).
  • Auth par password : Dylan700/sftp-upload-action n'accepte pas de clé SSH. Rotation manuelle, stockage en secret GitHub. Acceptable tant que le compte IONOS ne permet pas la clé.
  • Dépendance à une action tierce : Dylan700/sftp-upload-action@latest n'est pas officielle. Mitigation : elle est déjà en prod sur kanban-vibe sans incident.
  • Pas de preview deploys : les changements ne sont visibles qu'après merge. Acceptable en solo direct-to-main ; à rouvrir si le workflow devient multi-contributeurs.

Neutres :

  • Python + Node dans le même job : le build installe les deux runtimes. Temps de CI ~2–3 min, acceptable pour un site doc.
  • Artefact build séparé du deploy : permet de re-déployer sans rebuilder (via workflow_dispatch côté deploy si on l'isolait — pour l'instant on reconstruit).

Règle dérivée

Pour tout projet *.aelworks.fr, suivre cette stack : IONOS mutualisé + Dylan700/sftp-upload-action dans GitHub Actions, sous-domaine avec credentials SFTP dédiés, secrets préfixés par le nom du projet.

Le jour où un projet nécessite réellement un VPS (backend, SSR, websockets), cette ADR sera superseded par une nouvelle qui documentera le bascule.

Non-objectifs de cette vague

  • Atomic swap (uploader vers ./.new/ puis swap) — non supporté par l'action SFTP utilisée.
  • Clé SSH au lieu de password — nécessiterait un changement d'action et de compte IONOS.
  • Preview deploys per branch — reporté tant qu'on reste en solo direct-to-main.
  • Monitoring/observabilité (uptime, cert expiry) — non critique pour une doc statique.

Références