Le site est servi, mais ce n'est qu'une page d'attente. Cette page te donne une commande, ./scripts/deploy.sh, qui construit le site sur ton portable, envoie seulement ce qui a changé dans un nouveau répertoire de version sur le serveur, bascule le site en ligne dessus en une étape atomique, supprime les anciennes versions au-delà des dernières, et vérifie que https:// répond. Une seconde commande revient en arrière. Les envois passent par un compte dédié, , avec sa propre clé, sans sudo, et dont la racine web est la seule possession.
Avant de commencer
Il te faut les pages 1 à 5 terminées : le dossier du projet sur ton portable (page 1), ssh vps qui te connecte en , et Caddy qui sert la page d'attente sur https://.
$curl -s -o /dev/null -w '%{http_code}' https:///200
Le rsync fourni avec le Mac n'est pas celui qu'il te faut. Installe rsync 3 avec Homebrew (installe d'abord Homebrew depuis brew.sh si la commande brew manque) :
$brew install rsyncPuis ferme ce terminal et ouvres-en un nouveau (Cmd+N dans Terminal). Le shell déjà ouvert peut continuer à lancer /usr/bin/rsync : il retient où il a trouvé une commande, et si Homebrew vient d'y être installé, son PATH ne contient pas encore /opt/homebrew/bin. Un nouveau shell relit ton PATH et trouve d'abord le rsync de Homebrew. Dans le nouveau terminal :
$rsync --version | head -1$rsync --version | head -1 | grep -o 'version 3'version 3
Créer l'utilisateur de déploiement
Ton compte admin a sudo ; le compte qui envoie le site ne doit pas l'avoir, et il reçoit sa propre clé. Sur le portable, crée la clé de déploiement si elle n'existe pas encore et copie sa moitié publique sur le serveur :
$[ -f ~/.ssh/id_ed25519_deploy ] || ssh-keygen -t ed25519 -N "" -C "deploy@laptop" -f ~/.ssh/id_ed25519_deploy$scp ~/.ssh/id_ed25519_deploy.pub vps:deploy.pubPuis connecte-toi au serveur comme d'habitude :
$ssh vpsSur le serveur, installe rsync (le côté qui reçoit), crée l'utilisateur, laisse-le passer SSH, donne-lui la racine web, et installe la clé de déploiement pour lui, précédée de restrict. La dernière ligne, exit, te ramène sur le portable :
$sudo apt install -y rsync$sudo adduser --disabled-password --gecos "" $sudo usermod -aG sshusers $sudo chown -R : $sudo install -d -m 700 -o -g /home//.ssh$sed 's/^/restrict /' deploy.pub | sudo tee /home//.ssh/authorized_keys$sudo chown : /home//.ssh/authorized_keys$sudo chmod 600 /home//.ssh/authorized_keys$rm deploy.pub$exitAjouter l'alias sur le portable
Ajoute un second hôte dans ~/.ssh/config sur ton portable, à côté de vps :
$cat >> ~/.ssh/config <<'EOF'$$Host vps-deploy$ HostName $ Port $ User $ IdentityFile ~/.ssh/id_ed25519_deploy$ IdentitiesOnly yes$EOF$ssh vps-deploy 'ls 'current releases
Si tu obtiens Permission denied (publickey)
Par ordre de probabilité : l'utilisateur n'est pas dans le groupe sshusers, les droits sur /home//.ssh sont trop ouverts, la ligne de clé a perdu son préfixe ssh-ed25519, ou le chemin IdentityFile ne correspond pas à la clé que tu as créée. Sur le serveur, sudo journalctl -u ssh -n 20 donne la raison.
Écrire le script de déploiement
Crée le dossier scripts dans le projet :
$cd && mkdir -p scriptsPuis écris scripts/deploy.sh : copie la commande et colle-la dans le même terminal. Le chemin est relatif, donc le fichier atterrit dans le dossier du projet où tu viens d'entrer.
#!/usr/bin/env bash# Build the site and publish it as a new release. Usage: ./scripts/deploy.shset -euo pipefailcd "$(dirname "$0")/.."HOST=vps-deployROOT=KEEP=[ "$KEEP" -ge 1 ] || { echo "KEEP_RELEASES must be at least 1" >&2; exit 1; }npm cinpm run buildtest -f out/index.htmlREL=$(date -u +%Y%m%dT%H%M%SZ)echo "Release $REL"rsync -rlpz --checksum --delete --chmod=D755,F644 \ --link-dest="$ROOT/current/" \ out/ "$HOST:$ROOT/releases/$REL/"ssh "$HOST" "cd $ROOT && ln -sfn releases/$REL current.tmp && mv -T current.tmp current"ssh "$HOST" "cd $ROOT/releases && ls -1d 20* | sort | head -n -$KEEP | xargs -r rm -rf --"curl -fsS -o /dev/null -w '%{http_code}\n' https:///Rends-le exécutable, pour qu'il se lance en ./scripts/deploy.sh :
$chmod +x scripts/deploy.shDéployer pour la première fois
Lance le script depuis le dossier du projet. La dernière ligne affichée doit être 200 ; ouvre https:// et ton site remplace la page d'attente. Le premier envoi transfère tout le site (environ 220 Mo avec les médias de public/) ; les suivants seulement ce qui a changé.
$cd $./scripts/deploy.sh$ssh vps-deploy 'readlink /current | cut -c1-11'releases/20
$ssh vps-deploy 'rm -rf /releases/placeholder'Revenir en arrière
Revenir en arrière, c'est refaire la bascule vers une version plus ancienne. Ce script pointe current vers la version juste avant celle en ligne, ou vers celle que tu nommes. Copie la commande et colle-la dans le terminal, dans le dossier du projet :
#!/usr/bin/env bash# Usage: ./scripts/rollback.sh [release-name]set -euo pipefailHOST=vps-deployROOT=CUR=$(ssh "$HOST" "readlink $ROOT/current")CUR=$(basename "$CUR")LIST=$(ssh "$HOST" "cd $ROOT/releases && ls -1d 20* | sort")if [ $# -gt 0 ]; then TARGET=$1else TARGET=$(printf '%s\n' "$LIST" | awk -v c="$CUR" '$0 == c { print p; exit } { p = $0 }')fi[ -n "$TARGET" ] || { echo "No release older than $CUR." >&2; exit 1; }printf '%s\n' "$LIST" | grep -qx "$TARGET" || { echo "Unknown release: $TARGET" >&2; exit 1; }ssh "$HOST" "cd $ROOT && ln -sfn releases/$TARGET current.tmp && mv -T current.tmp current"echo "current: $CUR -> $TARGET"curl -fsS -o /dev/null -w '%{http_code}\n' https:///Rends-le exécutable, déploie une fois de plus pour que le serveur ait deux versions, liste-les, et reviens à la première :
$chmod +x scripts/rollback.sh$./scripts/deploy.sh$ssh vps-deploy 'ls -1 /releases'$./scripts/rollback.shTerminé
Un déploiement tient maintenant en une commande, ./scripts/deploy.sh, et un retour arrière en une autre, ./scripts/rollback.sh. Chaque version est un répertoire nommé par l'heure UTC de son déploiement, celle en ligne est celle vers laquelle pointe current, et le passage de l'une à l'autre est un seul renommage. Le serveur garde les dernières.
La page suivante, Sauvegardes, surveillance et la routine mensuelle, fait en sorte que tu sois prévenu quand le site tombe, et que le serveur puisse être reconstruit si le VPS est perdu.