I am used to deploying websites using my web editor Espresso. Espresso offers an excellent publishing engine that uses SFTP. But this method still requires some clicking around. I wanted automatic deployment! The first step was to choose a method for transferring the website to my web host.

Jekyll, the tool I use to generate this website, offers a long list of deployment methods. I wanted something not too complicated, that fits the limitations of my shared hosting environment.


The Jekyll documentation mentions using rsync for deployment. Rsync synchronizes files between two locations. It only sends differences in files, making it much faster than copying the entire website. Rsync works over ssh. Luckily, my web host provides ssh access.

Basic usage

The basic usage of rsync is:

rsync options sourcePath remoteUsername@remoteServer:remotePath

In my use case sourcePath is the directory where Jekyll generates the site, remoteUsername is the username I use to log in to the webserver, remoteServer is the URL of the webserver and remotePath is the directory from where my website is hosted.


Rsync needs some configuration to work properly with Jekyll. I found an article by Guillermo Garron that explains this. Jekyll recreates the entire site when you add a post. This will change the creation date of files and tricks rsync into thinking all posts have changed. So rsync needs to ignore the timestamp and look for the checksum instead. Use the option -c (checksum) for this.

Rsync should also delete files on the webserver that are no longer part of the local directory. For example when you remove a post locally, you also want it removed from the webserver. Use the option --delete for this. Be aware that this will remove all other files and directories you might have on the server (see below).

Since I am new to rsync I also had to look up some other common options. The option -v (verbose) gives information during the file transfer (without this option rsync is completely silent). The option -r (recursive) also transfers subdirectories. The option -z compresses the data that is being sent.

A lot of sample scripts I found use the option -e "ssh". This tells rsync to use ssh as the remote shell program. But as of rsync 2.6, ssh is the default and this option is no longer needed.

This is the resulting command:

rsync -vrzc --delete sourcePath remoteUsername@remoteServer:remotePath

Trying it out

Rsync allows you to do a dry run with the option -n. This is very useful since the command has the potential to completely mess up your live website. Especially with the option --delete turned on. I have a different site running in a subdirectory. This site is not generated by Jekyll. The dry run revealed that rsync will remove this subdirectory. Therefore I needed to exclude the subdirectory using --exclude '/subdirectory'.

The final command:

rsync -vrzc --delete --exclude '/subdirectory' sourcePath remoteUsername@remoteServer:remotePath


The next step is to make the rsync command part of a script, so I don’t have to type it in for every deploy. I will write an other post about that.