Something I wanted to try out since I set up the blog as hugo static site was the automatic testing and deployment straight from the git to our webserver. As we are not using any of the common hosts for static sites, because why would we when we have a server at our disposal, it was a interesting to find a solution without using third-party services.
Our current setup is a VPS running a nginx and a docker environment for everything we don’t quite trust and or want to run on bare metal. Two of those docker containers are Gogs and Drone CI, which work miraculously well together.
The later has quite the list of possible deploy/publish plugins including
scp
, sftp
and rsync
. I chose the rsync
plugin which I set up with the
rssh
shell on the server side. But the other two are also valid choices for
this task but they do require direct config entries in the sshd_config
to
restrict user access.
The drone configuration lives in the root of the hugo-site git in the
.drone.yml
file and would look something like this:
build:
image: debian:stretch
commands:
- apt-get update && apt-get -y install hugo python-pygments
- hugo
publish:
rsync:
host: ring0.de
user: hugo-deploy
source: public/
target: /blog
delete: true
recursive: true
drone.io internally uses docker containers for basically everything, which means
images, plugins and so on are not limited to some predermined ones but can be
basically anything. I am using an official drone publisher instance with
drone-rsync
.
On the server side I installed rssh via the usual channels then added a user for the upload. The login for the user is limited to the ssh key automatically generated by drone for every repository. A very nifty little feature.
adduser --system --group blog --home /var/lib/hugo --shell /usr/bin/rssh hugo-deploy
The rssh is configured by adding a single line to the bottom of /etc/rssh.conf
user=hugo-deploy:002:100000:/var/lib/hugo
The format for this line is not quite obvious but it is somewhat explained by
the example lines: user=<user>:<umask>:<action bitfield>:<chroot>
.
And because it is a real chroot it needs a bit of a setup before you can use it.
rssh comes with a script which adds all the necessary files to the user chroot
for the programs you need.
As rsync is not added by default I
patched
the script up little to also copy rsync.
Then execute the script, copying all the necessary files
(mkchroot.sh /var/lib/hugo
) and create a directory within the chroot with
write permissions for the deploy user.
Set up your nginx to serve the deploy user directory and tell drone to hook into
the Gogs repository and you are done. Every push to the repo should now be
automatically build, tested and then deployed to the server. In case you want to
commit something without it being deployed you can simply add a [ci skip]
to
the commit message.
Removed the usage of local builder tools as drone.io now seems to to only work with registries instead of locally available images. And running an additional docker registry just for the few updates we add to this blog seems pointless.