Vous pouvez naviguer parmi les posts en glissant votre doigt.

Automatization of Jekyll websites deployment

12th August 2016 . category: code .
#jekyll #nginx #tutorial #deployment

Automatization of Jekyll websites deployment

Jekyll is a pretty powerful framework to quickly build nice & functional static websites. I use it to develop websites that don’t need any database and that can be deployed on only one machine.

How will this work: we work with Jekyll on our computer, and when we’re happy with a version, we deploy it so that the internet users car admire the final result. So, we will, in that order:

  • generate the local website;
  • configure nginx;
  • write a bash script to deploy the Jekyll generated site on a distant server.

What we can get:

  • for the same site hosted on several servers, deploy a new version from any machine owned by a site contributor;
  • for several websites hosted on a same server, deploy one of the other website from any machine owned by a contributor of the selected website;
  • the same thing with several websites hosted on several servers, if you understood how it works (what I expect you to do at the end of this tutorial!).

Why not Git?

  • because you don’t want to deploy after each commit. You can want to commit without changing what the users see;
  • because you may not want to have to commit in order to deploy. Sometimes what you have is good and you just want to deploy it on another machine;
  • because the method described on Jekyll website requires two things that tickle me: to have Jekyll installed on the distant server, and pushing the whole code to build it again. We already have the website built, so why not using it!
  • chances are you’ll have to deploy a website on a machine on which you have few rights and you can’t install Git or Jekyll;
  • because you have to make the distinction between the deliverable (the website generated) and the lines you’ve written to deliver it (the versioned code);
  • and because seeing that it seems to be what everybody does, so, let’s be original (and do like me in this tutorial). Jokes aside, I studied several solutions (gulp, Git with hooks, scp, etc.) before adopting this one. It may have its cons (don’t hesitate to tell me which ones), but for the moment it corresponds exactly to my needs: make it quick and simple.

Prerequisites:

To have Jekyll (and know how to make sites with it!) and rsync on your computer, nginx and rsync installed on the distant machine. rsync is by default installed on some Linux distributions; to check, you just have to type rsync --version and if you don’t have the rsync version, well… just sudo apt-get install rsync! Of course, what I will describe also works with apache, but, well… I prefer nginx. I’ll explain why some day in a post. It would be because of its speed and user-friendliness, I would say.

I strongly suggest to buy a domain name. I don’t have any preference for that (I know amen offers ones at very good prices), I prefer to vary the companies where I buy domain names. Let’s say that for this tutorial your domain name is hailcaesar.com (you can be a fan, and I like to see websites honoring my glory spreading all over the web).

Let’s go!

Let’s start by creating our Jekyll website on our computer:

jekyll new site_hailcaesar

You can then do whatever you want with the website. Don’t forget to jekyll build to have everything you need in the _site folder or in any custom folder you configured to be the deliverable folder.

Now you have to configure the server. On it, you need to create the folder containing the website. Personally, because I like to be original, I usually put it in /var/www/. And don’t forget to change the rights on the folder:

cd /var/www
sudo mkdir site_hailcaesar
sudo chown -R www-data:www-data /var/www/site_hailcaesar/

Always on the server, you have to configure nginx so that it redirects the user correctly. To make it simple, we’ll copy a default configuration and edit it:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/hailcaesar.com
sudo vi /etc/nginx/sites-available/hailcaesar.com

In this file, here is what you’ll write:

server {
        # listen to port 80
        listen 80;

        # several possible URL separated by a space
        server_name hailcaesar.com;

        # website's folder
        root /var/www/site_hailcaesar;

        # index page
        index index.html;

        # access and error logs
        access_log /var/log/nginx/hailcaesar.access.log;
        error_log /var/log/nginx/hailcaesar.error.log;

        # returns 404 if it doesn't find anything
        location / {
                try_files $uri $uri/ =404;
        }
}

To activate the virtual host of your website, you have to create a symbolic link:

sudo ln -s /etc/nginx/sites-available/hailcaesar.com /etc/nginx/sites-enabled/hailcaesar.com

Now retart nginx to make the changes taken into account:

sudo service nginx restart

Nginx is now ready and you can test the URL http://hailcaesar.com, you’ll be ont your Jekyll website.

Let’s automatize the deployment with only one script!

With only one command, we’ll synchronize all the _site folder (-r) or any custom folder configured in _config.yml with the distant folder, and we’ll delete obsolete files (--del) and force the overwriting by more recent files (--force). I also want to know what happens during the deployment (-v) and check the progress (-P).

To do this, I created a script, deploy_jekyll.sh, that I execute everytime I’m happy. With the website development, I mean, because I’m often happy for any reason without wanting to deploy anything. The script will check in your configuration if you chose another destination folder than _site.

Here is what the beast looks like. Put it directly in your Jekyll folder (site_hailcaesar here). You can fetch the version I update regularly on Github. It contains more options:

#!/bin/bash
url='vivecaesar.com'
dest_folder='/var/www/site_hailcaesar/'
site_folder='_site'
echo "Looking for custom destination folder"
folder=$(sed '/^#/d' _config.yml | grep '^destination:' | cut -d: -f2| sed -e 's/[[:space:]]//')
if [ -z "$folder" ]
then
  echo -e "[\e[33mINFO\e[0m] No custom folder found"
else
  echo -e "[\e[33mINFO\e[0m] Custom folder found: \e[33m$folder\e[0m"
  site_folder=$folder
fi

rsync -rvP --del --force ./$site_folder/ $url:$dest_folder 2>rsync-errors
if  [ $? == 0 ]
then
  echo -e "[\e[32mOK\e[0m] Website deployed successfully on \e[34m$url\e[0m in the folder $dest_folder"
else
  echo -e "[\e[31mERREUR\e[0m] The website couldn't be deployed on \e[34m$url\e[0m in the folder $dest_folder \n\e[4mError list:\e[24m"
  cat rsync-errors
fi

Don’t forget the traditionnal sudo chmod 777 deploy_jekyll.sh if you want to execute this script. I put 777 because I usually commit it with with git and I want the other developers to be able to use and edit it. I’m sharing. Only with my code, I prefer to be clear about that, my wife being beautiful I don’t want you to be mistaken.

I put colors in the script so that it’s more readable, green meaning it’s a success and red… well the opposite! The website is emphasized in blue. The error list is displayed if required, and there are parameters (URL and destination folder).

Watch out when executing the script for the first time, you can get this message:

The authenticity of host 'hailcaesar.com (88.123.12.1)' can't be established.
ECDSA key fingerprint is SHA256:yEIAo2duX9+abcds4d2Ttw6fYx6u7E6661yrKF5Et6g.
Are you sure you want to continue connecting (yes/no)?

Even if you’ve already connected to the distant machine with its IP address, you’re now doing it with a particular host name, so it asks you if you want to go on. Just write yes and you’ll get the message:

Warning: Permanently added 'hailcaesar.com' (ECDSA) to the list of known hosts.
sending incremental file list

Last thing to do: in the build, Jekyll should ignore deploy_jekyll.sh and rsync_errors. To do so, you have to edit _config.yml and put this line: exclude: [deploy_jekyll.sh, rsync-errors].

And there you go! Pretty simple, no? No heavy machinery, no thousands of things to install and configue. You can develop and commit if you want to, but you master the deployment. A simple ./deploy_jekyll in Jekyll working directory and you’re set!


Me

DJ Caësar 9114 is a DJ who also codes. He's too lazy to make two different websites, so he made only one, uniting these two passions.