How to automatically deploy static web site to the hosting

The problem: publishing your web site efficiently

When web site is updated on a regular basis (as it happens with blogs) it becomes important to automate the process of uploading site to the hosting. Using cpanel or FTP is boring and time-consuming.

The goal is to be able to sync the static-generated content (e.g., _site directory generated by Jekyll) with just one command. My post refers to Jekyll and hostgator but the methods suggested are not limited to these platforms — they are applicable to any static-generated web content.

Possible solutions

Three approaches are dominating:

  • Use Jekyll-friendly web hosting. E.g., GitHub Pages. In this case you just need to push Jekyll files to the repository, server takes them and builds your web site. This approach limits the number of available hosting platforms and Jekyll features which can be used. E.g., it will not be possible to install custom plugins to Jekyll.
  • Put generated web site into git repository and sync using git. Arlo Carreon describes this approach in detail. It's not my choice — I find it awkward to put generated files under source version control. It also introduces stupid problems — like a need to add and remove these files from a repository, put meaningless comments for commits etc.
  • Torrents and RSS feed. This is a great method to deploy static content over many servers. Requires relatively complicated setup and is typically used with VPS servers. Probably an overkill for a simple web-site like a blog.
  • Use rsync. This is my choice. It's fast, straight-forward and logical. It just replicates the files from your computer to the hosting server.

I will describe rsync-based solution in detail. You need to have (user, non-root) ssh access to the hosting server in order to use this approach.

Step 1: Install rrsync to your home folder (server-side)

We will use certificate-based authorization to simplify the publishing process. It makes sense to restrict rsync access only to the directory which it is supposed to sync.

That's why rrsync wrapper shall be installed. If it is not already installed by your hoster you can do it yourself:

  • download rrsync
  • Put it to the bin subdirectory of your home folder (~/bin)
  • Make it executable (chmod +x)

Step 2: Setup certificate-based ssh access (server side)

This process is described in a lot of places in the net. I will not explain it in details here. What is different from usual approach is to put the restriction to certificate-based authorization in ~/.ssh/authorized_key). We will launch rrsync utility and supply it with the folder it shall have read-write access to:

command="$HOME/bin/rrsync <folder>",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa <cert>

<folder> is the path to your site. E.g., ~/public_html/you.org/blog-html/.

Step 3: Rsync! (client-side)

Add the script transfer.sh to the web site source folder:

#!/bin/sh

rsync -avr --rsh='ssh -p2222' --delete-after --delete-excluded   <folder> <user>@<site>:

Command line parameters are:

  • --rsh='ssh -p2222' It is needed if your hoster provides ssh access using ssh port different from default one (e.g., this is what hostgator is doing)
  • <folder> is the name of the local folder with generated web content. By default it is _site/ for Jekyll
  • <user> — ssh user name for your hosting account
  • <site> — your hosting server

My command line is:

rsync -avr --rsh='ssh -p2222' --delete-after --delete-excluded   _site/ hostuser@vrepin.org:

Don't forget column ':' after server name!

Optional step 4: exclude transfer.sh from being copied to the output folder by Jekyll

This step is recommended if you use this how-to to deploy Jekyll-based web site. If you put transfer.sh script to the root folder of your project, Jekyll copies it to the output folder. This behavior can be changed in _config.yml. Just add the following line there:

# Do not copy these file to the output directory
exclude: ["transfer.sh", README.md]

We are done!

Now it's possible to publish your web site by launching ./transfer.sh script. If your ssh certificate is passphrase-protected, you are asked to enter the password.

It was simple, wasn't it?

If you have any questions, comments, improvements ideas - don't hesitate to comment under this post!

If you liked this post, you can share it with your followers or follow me on Twitter!

#blogging #hostgator #hosting #jekyll