I host fchauvel.net (this very website) on Gandi.net. I use Hugo to generate it and I explain below how, each time I update its content, I automatically upload the new website.
Upload to Gandi.net using LFTP
Gandi offers several hosting solutions, from which I have chosen
simple hosting. Generally, I use rsync
or scp
to upload all my
content in one go, but Gandi restricts access to either SFTP or GIT.
I eventually used lftp
to automatically synchronise my local content
with my Gandi host. lftp
is a very powerful
FTP client that supports many protocols, and above all, is
‘scriptable’. Here is the script I wrote:
#!/usr/bash -f
echo "
set sftp:connect-program 'ssh -a -x -i $PATH_TO_PRIVATE_KEY';
open -u $GANDI_LOGIN,xxx sftp://sftp.dc0.gpaas.net;
mirror -c -e -R $LOCAL_CONTENT $REMOTE_CONTENT" > upload_script.txt
lftp -f upload_script.txt
A couple of explanations, though:
-
lftp
is available in most Linux repositories. On Debian, I installed it usingapt-get install lftp
. -
You must replace
$PATH_PRIVATE_KEY
by the path to your own private RSA key (on your local machine). Remember to register the associated public key on the Gandi portal. If the Gandi.net portal rejects your key—as it did for mine—you can still manually edit the.ssh/authorized_keys
in a SFTP session opened with login and password (I use WinSCP in that case). -
$GANDI_LOGIN
stands for your user login (e.g., 123456). It appears on the Gandi portal, when you place your mouse on a small information sign next to the SFTP entry. -
You must provide a dummy password (
xxx
in my script) to avoid LFTP to prompt you for one. This would make your script hang if you use it to automate the upload (as shown below). -
Remember to use the
-d
option oflftp
to debug issues. I find it especially useful to investigate authentication failures.
Store Content on GitHub
I generate this website using Hugo. Hugo converts articles written as simple Markdown files into complicated HTML pages. I secure these Markdown files along with Hugo’s configuration in a dedicated GitHub repository and when I push some changes to GitHub, I want the site to be regenerated and redeployed, automatically.
The trick is to install Hugo’s themes as Git submodules. If we do not,
git
would detect that themes are also GitHub repositories and their
content would be excluded from your repository. Any clone of your
repository would then lack its themes. To install a theme as a
submodule, I clone it using:
|
|
Now, when I checkout my website’s sources (say on the continuous
integration server), I must explicitly ask Git to also clone the
submodules (i.e., the themes). I either do git submodule update
--init --recursive
before to ask Hugo to build the website or I make
a recursive clone using git clone --recursive
https://github.com/me/mytheme.git
.
Automate Using Codeship.io
J.C. Lavocat explained how to automate the deployment of Hugo site
using
Codeship.io. He
uses rsync
instead of lftp
but his solution works just fine. Here
is how I adapted it:
# Install Hugo, directly from Github
go get -v -u github.com/spf13/hugo
cd ~/clone
hugo
# Mirror the content
echo "
open -u $GANDI_LOGIN,xxx sftp://sftp.dc0.gpaas.net;
mirror -c -e -R public $REMOTE_CONTENT" > upload_script.txt
lftp -f upload_script.txt
The downside is that we then automatically fetch the latest development version of Hugo’s sources, instead installing the latest stable release. From time to time the generation will fail because of some new and unstable features under development.
Or Automate Using Wercker
Hugo’s documentation actually suggests using Wercker. In my view, it is more convoluted, but it permits specifying a version of Hugo. I proceed as follows:
- Register to the Wercker website;
- Create a
wercker.yml
configuration (see below); - Create a deployment pipeline, and generate a new pair of RSA keys attached to the deploy step;
- Register your public RSA key on Gandi.net. (I had to do it manually, by editing the
.ssh/authorized_keys
).
Below is the wercker.yml
that eventually worked for me, after many
trials and errors—I must admit. I adapted Joseph Stahl’s
solution to deploy on Digital
Ocean. I change two things:
- I adjusted the build phase so that I also clone the themes as submodules.
- I do not fetch and store the private key manually, I
use the
add-ssh-key
step instead.
|
|