---
date: 2019-11-29T14:45:12+01:00
description: "Deploy a site, made with the generator Hugo, by rsync/ssh, SFTP+rsync, lftp client, or the powerfull rclone."
draft: false
tags: ['Hugo','deploy','chroot','lftp','rclone','rsync','SSH','SFTP']
title: "Hugo: Deploy SFTP"
translationKey: "hugo-deploy-sftp"
---
## Description
To deploy a static website, made with Hugo, some solutions exist:
* the easy is with the tool {{< anchor rsync rsync >}}.
* automated deployment solutions.
* I review a third for users SSH, under chroot contraints.
Into the simple context deployment, you need to create a file named `deploy`
at the root of your Hugo project.
## Utilisation
### rsync
To deploy a site with `rsync` is really simple. **rsync** is the tool to
synchronize datas; it's just do it!
Install the tool:
* on Debian/*Buntu : `# apt install rsync`
* on OpenBSD : `# pkg_add rsync` - {{< abbr FYI "for your information" >}},
since OpenBSD 6.5, it exists the tool `openrsync`;
*it's subject to the same problem described below!*
I presume you had an authentification SSH, *with key is better*.
```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}"
```
This example show the deployment with rsync using a SSH connection.
{{% note info %}}
Executing the command `hugo` regenerate all page. This results `rsync`
download again all page, and not only the modified.
{{% /note %}}
{{% note warning %}}
The problem: if the SSH user is under contraint chroot SSH, he can only
connect by {{< abbr SFTP "SSH File Transfer Protocol" >}};
he cant use **rsync** because the tool cant communicate on this protocol.
To bypass this problem, you need to use :
- {{< anchor sshfs sshfs >}} solution, before using `rsync`, or
- the thin {{< anchor lftp lftp >}},
- or the powerfull {{< anchor rclone rclone >}}.
{{% /note %}}
### SshFS
**SshFS** can be install with the package manager:
* on Debian/*Buntu : `# apt install sshfs`
* on OpenBSD : `# pkg_add sshfs`
{{% note info %}}
Under OpenBSD, you need to run SshFS with rights admins; use {{< man doas >}}.
To mount the filesystem:
`$ doas sshfs -C -p $port -o allow_other -o uid=$(id -u $USER) -o gid=$(id -g $USER) ${id}@${host}:${dir_dist} "${dir_mount}"`
{{% /note %}}
Once the connection is established, the remote folder is mounted locally
where you desired.
Now, it's time to use `rsync` as:
`cd "${dir_local}" && rsync -av --delete --human-readable --progress --stats "." "${dir_mount}"`
To unmount correctly:
`$ doas umount "${dir_mount}"`
With this in mind, see the file `deploy` under this SshFS+rsync context:
```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}" # for Debian
doas umount "${dir_mount}" # for OpenBSD
}
################################################################################
###
##
# Execution
##
###
################################################################################
hugo
status="$?"
if [ "${status}" -eq 0 ]; then
if _mount; then
_rsync
_umount
fi
fi
```
{{< note warning >}}
Be carefull: DO NOT USE directly this script without comment lines, segun
your OS!
{{}}
### lftp
**lftp** is a "Swiss Army knife" for the network connection. It run FTP(S),
HTTP(S) protocols, on IPv4, IPv6; and too, bittorent and partial WebDAV.
It can be mirroring documents and folders. And: SFTP!
Yes, you can mirror datas on SFTP!
----
To install by the package manager:
* on Debian/*Buntu : `# apt install lftp`
* on OpenBSD : `# pkg_add lftp`
See, this instance deployment:
```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}"
```
### rclone
**rclone** is a very powerfull CLI tool to duplicate on stockage solution,
as Cloud, differents filesystems, but too with SFTP.
Install by the package manager:
* on Debian/*Buntu: `# apt install rclone`
* on OpenBSD: `# pkg_add rclone`
In first, you need to configure by using the option `config`: `$ rclone config`
1. Name your **remote** access, as you wish. This will be use as remote
name connexion.
2. Choose absolutly SFTP connexion, to write `sftp` when the invite asks.
*See the {{< anchor documentation documentation >}} Rclone:SFTP!*
File config: `~/.config/rclone/rclone.conf`*, by default.*
Here this instance configuration:
```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
```
And here, this instance deployment:
```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
Voila: This is the end!
Now, you known how to deploy your static website Hugo, with `rsync/ssh`,
`sshfs+rsync`, `lftp`, or even by `rclone`.
## Documentation
* {{< gohugo s="hosting-and-deployment" n="deployment-with-rsync" >}}
* {{< gohugo s="hosting-and-deployment" n="" >}}
* the [lftp](https://lftp.yar.ru/) website.
* the [rclone](https://rclone.org/), and [rclone:sftp](https://rclone.org/sftp/) documentation page.
----