Skip to content

feat: SSH publish mode — deploy static sites to remote servers #7

Description

@vianmora

Ability to publish a site directly to a remote server via SSH/rsync, instead of serving it locally. Each site has its own SSH key and target server.

Plan d'implémentation

Architecture

Nouveau buildMode: "ssh" dans le publisher. La config SSH est stockée par domaine dans /var/work/<domain>/.

/var/work/<domain>/
├── state.json    # mode, sshHost, sshUser, sshPath, sshPort
└── ssh_key       # clé privée (chmod 600, jamais loggée)

Étape 1 — Endpoint de configuration SSH (webstudio-publisher)

Nouveau endpoint dédié — la clé privée n'est pas passée à chaque publish :

POST /ssh-setup
{
  "domain": "mon-site",
  "sshHost": "192.168.1.50",
  "sshUser": "deploy",
  "sshPath": "/var/www/mon-site",
  "sshPort": 22,
  "sshPrivateKey": "-----BEGIN OPENSSH PRIVATE KEY-----\n..."
}

Le publisher :

  1. Écrit la clé dans /var/work/<domain>/ssh_key avec chmod 600
  2. Persiste le reste dans state.json
  3. Ajoute l'host au known_hosts via ssh-keyscan

Étape 2 — POST /publish (inchangé côté appelant)

{ "buildId": "...", "builderOrigin": "...", "buildMode": "ssh" }

Le publisher relit state.json du domaine pour retrouver la config SSH.


Étape 3 — publishBuildSsh() dans server.mjs

Pipeline :

webstudio sync → webstudio build --template ssg
→ patchDataFiles → npm install (si besoin) → vite build
→ rsync -avz --delete \
    -e "ssh -p $port -i /var/work/<domain>/ssh_key -o StrictHostKeyChecking=no" \
    /var/work/<domain>/dist/client/ \
    $user@$host:$path/

Étape 4 — docker-compose (webstudio-self-host)

/var/work est déjà monté en volume pour l'état SSR — les clés SSH s'y trouvent donc automatiquement. Pas de volume supplémentaire nécessaire.

S'assurer que rsync est présent dans l'image publisher (à ajouter dans le Dockerfile si absent).


Documentation à écrire

  • CLAUDE.md (webstudio-publisher) — section ssh dans le tableau des modes, note sécurité sur les clés
  • README.md (webstudio-publisher) — guide utilisateur complet :
    • Prérequis : rsync sur les deux machines, Nginx sur le serveur distant
    • Générer la paire de clés + ssh-copy-id
    • Exemple POST /ssh-setup puis POST /publish

Prérequis côté serveur distant

  • rsync installé
  • Nginx configuré pour servir $sshPath/<domain>/
  • Port SSH ouvert et clé publique déposée

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions