---
date: 2019-11-29T14:45:12+01:00
description: "Déploiement d'un site, fait avec le générateur Hugo, par rsync+ssh, SFTP avec rsync, le client lftp, voire rclone"
draft: false
tags: ['Hugo','deploy','chroot','lftp','rclone','rsync','SSH','SFTP']
title: "Hugo : Déploiement SFTP"
translationKey: "hugo-deploy-sftp"
---
## Description
Pour déployer un site fait avec le générateur de site statique **Hugo**,
il existe plusieurs solutions :
* la plus simple est l'usage de l'outil {{< anchor rsync rsync >}}.
* Il existe des "solutions" de déploiement selon le type de services que
vous utilisez.
* je vais vous en présenter une troisième solution tenant compte du fait
que votre utilisateur SSH soit soumis au chroot SSH.
Dans le contexte de déploiement "simple", il suffit de créer le script de
déploiement nommé `deploy` à la racine du projet Hugo !
## Utilisation
### rsync
Déployer un site avec `rsync` est très simple. **rsync** est l'outil pour
de la synchronisation de données ; il le fait, et il le fait bien.
Après avoir installé l'outil :
* sous Debian/*Buntu : `# apt install rsync`
* sous OpenBSD : `# pkg_add rsync` - pour information, depuis OpenBSD v6.5,
il existe nativement dans le système de base, l'outil `openrsync` ;
reproduisant le comportement de **rsync**, il est asujetti au même problème décrit ci-dessous -
En assumant le fait que vous avez une authentification SSH sur le serveur
où vous désirez vous synchroniser, et mieux une authentification par clé SSH.
```sh
#!/bin/sh
user=userid
host=servername
port=22
dir_dist=/remote_folder/
file_id="$HOME/.ssh/id_ed25519"
hugo && rsync -avz --delete -e "ssh -i ${file_id} -p ${port}" public/ "${user}"@"${host}":"${dir_dist}"
```
* `userid` est l'identifiant utilisateur SSH
* `servername` est le nom {{< abbr FQDN "Fully Qualified Domain Name" >}}
ou l'adresse IP du serveur SSH vers lequel se connecter
* `remote_folder` est le nom réel du répertoire distant sur lequel se connecter.
Cet exemple montre le déploiement d'un site avec rsync utilisant une connexion SSH.
{{% note info %}}
L'exécution de la commande `hugo` va regénérer chacune des pages. Résultat,
`rsync` va téléverser à nouveau toutes les pages, et non pas juste celles
modifiées, puisque toutes sont re-générées.
{{% /note %}}
{{% note warning %}}
Le problème est que si l'utilisateur SSH est soumis au chroot SSH, et donc
ne peut se connecter qu'en {{< abbr SFTP "SSH File Transfer Protocol" >}},
il est impossible d'utiliser **rsync** car il n'est pas fait pour communiquer
ainsi ; tout simplement, il ne le peut pas !
C'est là, qu'entre en jeu, soit :
- le fait de se connecter en premier avec {{< anchor SshFS sshfs >}}
- ou d'utiliser le très léger client {{< anchor lftp lftp >}}.
- voire le puissant logiciel {{< anchor rclone rclone >}}.
{{% /note %}}
### SshFS
**SshFS** peut être installé par votre gestionnaire de paquets :
* sous Debian/*Buntu : `# apt install sshfs`
* sous OpenBSD : `# pkg_add sshfs`
L'avantage de *SshFS* est que c'est un outil qui permet de se connecter
que votre utilisateur SSH soit soumis ou non à un chroot SSH en montant
le répertoire distant dans l'espace utilisateur local. *Attention, cela
ralentit l'accès réseau, rien de grave, mais à savoir…*
Sous OpenBSD, c'est un peu plus délicat ; du fait de fonctionner principalement
sur ce {{< abbr SE "Système d'Exploitation" >}}, j'expliquerais
pour celui-ci. Au cas où, adaptez à votre cas.
En effet, sous OpenBSD, il est nécessaire d'avoir des droits administrateur,
et il est recommandé d'avoir paramétré {{< man doas >}}.
Pour monter localement le système de fichier :
`$ doas sshfs -C -p $port -o allow_other -o uid=$(id -u $USER) -o gid=$(id -g $USER) ${id}@${host}:${dir_dist} "${dir_mount}"`
Une fois connecté, le répertoire distant est monté localement là où vous
le désirez.
C'est le moment d'utiliser `rsync` mais au lieu de chercher à se
connecter - *puisque c'est déjà fait* -, l'outil va permettre de synchroniser
d'un répertoire source local vers le répertoire source distant, monté localement.
**rsync** s'utilise donc ainsi :
`cd "${dir_local}" && rsync -av --delete --human-readable --progress --stats "." "${dir_mount}"`
Pour le démonter proprement, ce sera :
`$ doas umount "${dir_mount}"`
Ceci étant dit, voici à quoi peut ressemble le fichier de déploiement
dans ce contexte SshFS + rsync :
```sh
#!/bin/sh
#set -x
[ -n "$TERM" ] && clear
ROOT="$(dirname "$(readlink -f -- "$0")")"
id=userid
host=servername
port=22
### the directory where your web site files should go
## dir_dist: relative to chroot SSH
dir_dist="/www/"
dir_local="$ROOT/public/"
dir_mount="$HOME/servers/${id}/"
file_id="$HOME/.ssh/id_ed25519"
rsync_opts="--human-readable --progress --stats "
################################################################################
###
##
# Fonctions
##
###
################################################################################
_mount() {
[ ! -d "${dir_mount}" ] && mkdir -p "${dir_mount}"
# for Debian
[ -d "${dir_mount}" ] && sshfs -C -p $port -o uid=$(id -u $USER) -o gid=$(id -g $USER) -o IdentityFile="${file_id}" ${id}@${host}:${dir_dist} "${dir_mount}"
# for OpenBSD
[ -d "${dir_mount}" ] && doas sshfs -C -p "${port}" -o allow_other -o uid=$(id -u $USER) -o gid=$(id -g $USER) -o IdentityFile="${file_id}" "${id}"@"${host}":"${dir_dist}" "${dir_mount}"
}
_rsync() {
cd "${dir_local}" || exit
rsync -av --delete $rsync_opts "." "${dir_mount}"
}
_umount() {
fusermount -u "${dir_mount}" # pour Debian
doas umount "${dir_mount}" # pour OpenBSD
}
################################################################################
###
##
# Execution
##
###
################################################################################
hugo
status="$?"
if [ "${status}" -eq 0 ]; then
if _mount; then
_rsync
_umount
fi
fi
```
* `userid` est l'identifiant utilisateur SSH
* `servername` est le nom {{< abbr FQDN "Fully Qualified Domain Name" >}}
ou l'adresse IP du serveur SSH vers lequel se connecter
* `dir_mount` est le nom du répertoire local vers lequel le répertoire
distant va être monté.
{{< note warning >}}
ATTENTION à ne pas utiliser directement ce script, sans mettre en commentaire
les lignes ne correspondant pas à votre OS !
{{}}
### lftp
**lftp** est un couteau suisse de la connexion réseau. Il fait du FTP,
FTPS, de la synchronistation de document, sur IPv4, IPv6, au-travers des
protocoles HTTP(S) ; il fait même du trafic bittorent, voire partiellement
du WebDAV… et il est capable de se connecter en SFTP !
Voilà le "miracle" : un client réseau sachant faire du mirroring de données
en SFTP !!!
Donc, installez avec votre gestionnaire de paquets le binaire :
* sous Debian/*Buntu : `# apt install lftp`
* sous OpenBSD : `# pkg_add lftp`
```sh
#!/bin/sh
#set -x
[ -n "$TERM" ] && clear
ROOT="$(dirname "$(readlink -f -- "$0")")"
id=userid
host=servername
port=22
### the directory where your web site files should go
## dir_dist: relative to chroot SSH
dir_dist="/www/"
dir_local="$ROOT/public/"
file_id="$HOME/.ssh/id_ed25519"
hugo
lftp -e "set ftp:ssl-allow no; set sftp:connect-program ssh -a -x -i ${file_id}; mirror -e -R ${dir_local} ${dir_dist}; quit;" -p "${port}" sftp://"${id}":"${passwd}"@"${host}"
```
* `userid` est l'identifiant utilisateur SSH
* `servername` est le nom {{< abbr FQDN "Fully Qualified Domain Name" >}} ou l'adresse IP du serveur SSH vers lequel se connecter
### rclone
**rclone** est un puissant outil en ligne de commande pour gérer le stockage
de fichiers à-travers de nombreuses solutions de type nuage informatique,
systèmes de fichers divers et variés, mais aussi basiquement par le biais
du protocol SFTP.
Installez avec votre gestionnaire de paquets le binaire :
* sous Debian/*Buntu : `# apt install rclone`
* sous OpenBSD : `# pkg_add rclone`
La configuration par l'usage de l'option `config` tel que : `$ rclone config`
1. Nommez votre accès **remote**, tel que vous désirez. Ce nom sera à utiliser
en tant que nom de connexion.
2. Choisissez absolument la connexion SFTP, en écrivant `sftp` lorsque l'invite
vous pose la question.
L'invite de commande de rclone est en anglais, mais elle est aisée à utiliser.
*Je vous renvoie à la page de la documentation SFTP, dont la référence est
dans la section {{< anchor Documentation Documentation >}} ; allez-y absolument
faire un tour de lecture !*
Le fichier de configuration se trouvera être écrit dans votre répertoire
personnel `~/.config/rclone/rclone.conf`, par défaut.
Il sera de ce type :
```conf
[nom_remote]
type = sftp
host = adresse_ip ou FQDN
user = id_ssh
port = 22
key_file = ~/.ssh/id_ed25519
key_use_agent = true
pubkey_file = ~/.ssh/id_ed25519.pub
use_insecure_cipher = false
md5sum_command = none
sha1sum_command = none
```
Il ne reste plus qu'à utiliser rclone dans votre script de déploiement d'Hugo :
```sh
#!/bin/sh
#set -x
[ -n "$TERM" ] && clear
ROOT="$(dirname "$(readlink -f -- "$0")")"
id=userid
host=servername
port=22
### the directory where your web site files should go
## dir_dist: relative to chroot SSH
dir_dist="/www/"
dir_local="$ROOT/public/"
file_id="$HOME/.ssh/id_ed25519"
rclone_remote="nom_remote"
hugo
rclone sync -i "${dir_local}" "${rclone_remote}":"${dir_dist}"
```
## FIN
Voilà, c'est fini.
Maintenant, vous savez déployer votre site statique Hugo, que avec `rsync/ssh`, `sshfs+rsync`, `lftp`, voire par `rclone`.
## Documentation
La documentation officielle :
* {{< gohugo n="deployment-with-rsync" s="hosting-and-deployment" a="shell-script" >}}
* Le site web de [lftp](https://lftp.yar.ru/)
* La documentation de [rclone:sftp](https://rclone.org/sftp/)
---