Skip to content

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

@vianmora

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions