Prologue

With hammer and chisel

When this site started to exist, already in 2005 (the domain name was registered on June 11th, 2004, a highly unimportant day), it was handmade. As a good computer craftsman, I made it undergo transformations according to the technologies. Thus, one could see on this site, pages entirely written with a text editor.

Before that, having no hosting and even less domain name, I even owned a site on Multimania. I was especially proud of the side menu made with a Java applet. By the way, this was my first experience with Java code that I had decompiled to remove the license key control.

The industrial era

But on alleluia.ch, I did not repeat the feat of the Java applet. I went straight to the hard way. At first, I coded in HTML. I almost had the idea to design myself a framework in PHP to manage my pages. Fortunately, this madness didn’t even involve the beginning of a little coding. Long hours were saved and the full nights of sleep that followed invigorated me.

Very quickly, there was talk of not coding these pages by hand anymore. That’s why I implemented something very trendy at the time: a CMS!

My choice was Joomla! which was certainly a 1.0.x version. The very beginning of this CMS.

I even created extensions for Joomla!: a tag cloud - who still remembers that - as well as an extension that randomly displays the famous Chuck Norris facts.

Yes, it was the height of fun back then. Better than TikTok.

For several years, I maintained this instance of Joomla! as well as others used by other sites - almost against my will. The Joomla! updates were quite painful. They were not automated. The one-click update didn’t come until much later.

When I was an intern at the Post, Kay Graham gave me a great piece of advice. She said, “Don’t be too good at a job you don’t want.”

Tina Fey as Cinda Canning in the show Only Murders in the Building

Degrowth

You have to know that Joomla! is still more than 9’000 files to serve, in my case, a few unfortunate pages. Add to that the maintenance of the database which must also be maintained. All this is not a sinecure.

So I thought long and hard and I tested several types of CMS called flat. Meaning “flat file” CMS, that is to say a CMS with a flat file for the database.

In addition, platform services to build your own website, while very appropriate in many cases, were not really an option for me, as I did not want to take out an additional and more expensive subscription to the one I already had for my email and other websites.

It is thus in the course of my tribulations, that it came to my mind that there were website generators.

And there, a new era had begun for Alleluia! Jekyll would be the generator of this site.

Back to basics

In my case, the main barrier was selecting and maintaining a theme for my site. Even if it is true that I know how to navigate in the murky waters of HTML and CSS, I prefer to avoid it. For this reason, I quickly turned to the selection of a theme for the site among the existing online offer.

In the field of free and open source themes, the choice is vast, but I didn’t find the one that seemed appropriate. This is obviously a matter of personal taste.

In addition, there were a few criteria that were important to me: a search within the site and the ability to adapt a few things like colors, fonts, etc. After many hours of research, I finally found a theme, paying of course, but at a reasonable price.

You should know that when you buy a theme for Jekyll, you actually get all the source code of the theme. Indeed, it is not possible for the vendor to encapsulate it in some kind of sealed and signed package.

This was a huge advantage for me, because I made a lot of improvements; at least, that’s how I see it.

To get started with Jekyll, I highly recommend the official documentation. Below you have a brief overview explaining how to create a site from scratch.

Getting started with Jekyll

The source code follows the structure given by Jekyll. Everything is documented here. If you want to create a site yourself from scratch, the main prerequisite is Ruby. You don’t need to know the language, but Jekyll is written in this language.

Depending on your context, you will have to install Ruby. This installation is explained here. For example, on macOS, the easiest way is to install Homebrew and then install Ruby and Jekyll and Bundler (Ruby package dependency manager, the Gems).

brew install ruby
gem install jekyll bundler

To generate a structure of a blank site {my-site}, the following command is executed:

jekyll new {mon-site}

Then go to the directory of the generated site

cd {mon-site}

To build the site

jekyll build

To start a local server serving the site

jekyll serve

Let’s move on and start preparing for site automation.

Preparation

This is all very pleasant. You have your theme and you have your old pages. What are the steps to get a functional site from that?

Retrieving the basic material

Several elements must be retrieved: the content of your pages, as well as all the media you refer to in your pages. You might even have some JavaScript code specific to a page.

If the content comes from a CMS, the easiest way is to perform a database query to retrieve the content of the pages. Usually, it is a mixture of HTML code and plain text.

For the media, usually they are stored in one or more directories on your hosting. In my case, the media types are images. But depending on the situation, you can imagine others: videos, JavaScript scripts, etc.

Then, you will have to convert the text of your pages into Markdown. I preferred to reformat my pages rather than find an HTML to Markdown converter.

This is not fundamentally necessary, as Jekyll can generate a site from the existing HTML code. Depending on the quality of the HTML code at the source, the generated result may therefore vary.

Hosting

As far as hosting is concerned, a site made with Jekyll requires extremely few prerequisites. Basically, you just need a web server that can serve resources: HTML, CSS, JPEG, WebP, JavaScript, etc.

My site is hosted on Metanet. As mentioned above, it is a hosting that I already had. So no need to change it.

Automation

This is probably the reason why you arrived on this article: how to automatically deploy a Jekyll site.

As with everything, there are always a thousand ways to do something. Look up how to make pasta on the internet and you’ll find 15’000 sites telling you how to heat the water before and put the pasta after. How to drain it and how to cool it, etc.

In my DevOps experience, you’ll be turned off in the same way. Far be it from me to offer an absolute version of deploying a Jekyll-generated site.

In my situation, I chose to do it using Azure DevOps. The main reason is that at the time I created my organization on Azure DevOps, Microsoft was the only Git repository provider that allowed for private repositories.

Principle of operation

In order to deploy a site, you also need the site’s sources. These are stored in a Git repository. From the repository, the sources are retrieved and processed by the Jekyll generator. Finally, the generated site is deployed on the appropriate environment.

Processus

The steps mentioned above are certainly not difficult to perform manually. However, they do require a local development environment and running commands in a terminal.

By automating these tasks, we focus on writing the articles and pages and not on setting up a development environment and this generation mechanics. That’s exactly what we’re going to automate.

A simple deployment pipeline in Azure DevOps, is described with a YAML file. There are other ways to describe the integration pipeline. The advantage of the YAML file is that it is saved in the source code repository along with the rest of the site.

The pipeline defines 3 main steps:

  1. The retrieval of the source code of the site
  2. The construction of the site from the source code
  3. The deployment of the generated site

The YAML file is called by default azure-pipelines.yml.

Source code retrieval

The source code of the site is stored in a Git repository along with the pipeline description file azure-pipelines.yml. In the pipeline descriptor, the retrieval of the source code is implicit. The content of the repository in which the pipeline descriptor is stored is therefore automatically retrieved at the time of the pipeline trigger.

However, the pipeline trigger must be indicated: the trigger element below. This element of the YAML file indicates that we take into account all the changes that are made in the repository for the launch of the CI/CD pipeline except those made in the _drafts directory and on the pipeline descriptor itself: azure-pipelines.yml.

I configured it this way, because I didn’t want to start the pipeline for changes that are not visible in the deployed site. Indeed, articles placed in _drafts are not published by Jekyll.

Also, I didn’t want a change in the pipeline descriptor to cause the site to be deployed even though it hadn’t been changed.

trigger:
  paths:
    exclude:
      - '_drafts/*'
      - 'azure-pipelines.yml'

Site construction

The construction of the site is the second step in this process. First, one chooses the environment on which the site will be built.

With Azure DevOps, one can choose from a list of several operating systems - presented as virtual machine images - which of these will be used for the build.

These virtual machine images prepared by Microsoft teams have the advantage of being up-to-date and having a large number of software components pre-installed. A complete list of these agents is available here.

Then, the deployment descriptor indicates the different steps of the pipeline. First, the build step. In this step, we first make sure we have the right version of Ruby. Then we install Jekyll and its dependencies. And finally, we execute the construction of the site.

To ensure that the generated content is passed on to the deployment stage, we copy and publish the built site in the pipeline.

pool:
  vmImage: ubuntu-latest

stages:
  - stage: Build
    jobs:
      - job: Package
        steps:
          - checkout: 'self'
            fetchDepth: '1'
            displayName: 'Checkout source code'
          - task: UseRubyVersion@0
            inputs:
              versionSpec: '>= 2.5'
            displayName: 'Install Ruby'
          - script: |
              gem install bundler jekyll
              bundle install --jobs=4
            displayName: 'Install bundles'
          - script: bundle exec jekyll build
            displayName: 'Build website'
          - task: CopyFiles@2
            inputs:
              SourceFolder: '$(System.DefaultWorkingDirectory)/_site'
              Contents: |
                **
                !*.yml
              TargetFolder: '$(Build.ArtifactStagingDirectory)'
            displayName: 'Copy website to staging directory'
          - publish: '$(Build.ArtifactStagingDirectory)'
            displayName: 'Publish website to pipeline'

Site deployment

The deployment of the site is done on your hosting. Since a Jekyll-generated site is a collection of HTML, CSS, JavaScript, etc., no special configuration is usually required on your hosting. Usually an upload via FTPS is sufficient.

At this last step, we retrieve the content from the previously published in the pipeline and push this content to the right place on the hosting.

The configuration of the connection for FTP access is done securely. No passwords are stored in the source code.

- stage: Production
  dependsOn: Staging
  jobs:
    - job: Deployment
      dependsOn: Verification
      steps:
        - checkout: none
        - download: 'current'
          displayName: 'Retrieve website from pipeline'
        - task: FtpUpload@2
          displayName: 'Upload website'
          inputs:
            credentialsOption: 'serviceEndpoint'
            serverEndpoint: 'FTP endpoint production'
            rootDirectory: '$(Pipeline.Workspace)/Build.Package'
            filePatterns: '**'
            remoteDirectory: '/'
            enableUtf8: true
            clean: false
            cleanContents: true
            preservePaths: true
            trustSSL: true

Your site is now deployed!

All you have to do now is write those articles you’ve been putting off writing for too long.