Making this website with Jekyll

A walk-through of how I made this easy to maintain but featureful static website using Jekyll based on a Docker development workflow. Although this required some ramp-up to getting started, making changes is trivial. All the steps outlined below should be easy to follow and include a brief explanation to help you learn!

Jekyll has become a popular tool for generating static websites for anything from blogs, project website or documentation portals. The main reason it got my attention was that it can give the appearance of a rich dynamic website but is ultimately just a set of generated HTML files. It also provides an easy way to mix HTML and markdown to get the flexibility you sometimes need with the simplicity you prefer which makes it easy to really add new content. Jekyll also powers GitHub Pages behind the scenes which allows you to serve content purely from your GitHub repository.

You are looking at the live version of this website based on the source repo eyjohn/ but NOT hosted on GitHub Pages.


By the end of this process, I want to:


Before trying this, you will need to know about the following:

Getting Started

Firstly, let’s create and initialise a workspace and install the necessary tools.

Creating the repository

git init

Setup Jekyll

I will be using docker to run jekyll rather than installing it on my system. This is because I plan on creating a CI/CD pipeline built on top of containers which I will explore in a future post. You can, however, install it natively on your system which I will not be covering.

I chose the jekyll/jekyll dockerhub images which are provided by this repo jekyll-docker and has great documentation. Let’s write a quick wrapper script to easier to invoke the container while we develop:


docker run --rm \
  --volume="$PWD:/srv/jekyll" \
  --volume="jekyll_cache_$(basename $PWD):/usr/local/bundle" \
  -it jekyll/jekyll "$@"

A fixed version can also be specified, although I just chose to use the latest available at the time (3.8.5).

NOTE: it is important that your Docker volume mounts work correctly, initially my setup: WSL + docker (minikube) did not preserve Unix execution mode correctly, and I lost HOURS to this as my gems would fail to install!

Get Jekyll to create a new site

I was impressed by the default website generated by Jekyll, had it not been for my preference of dark themes, I would have stuck with it. To get started simply run this command inside your directory:

./docker_run jekyll new .

Running it for the first time might take some time, also you may need to use –force if the directory is non-empty.

This generates the following files:
├── 404.html
├── Gemfile
├── Gemfile.lock
├── _config.yml
├── _posts
│   └── 2019-06-23-welcome-to-jekyll.markdown
├── docker_jekyll

Build and Serve website

You can now build (generate static files) or serve (build and serve over HTTP) this project. A jekyll serve --watch workflow is a popular development workflow. In my case I simply ran:

./docker_run jekyll serve --watch # takes a few seconds to start


ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux-musl]
Configuration file: /srv/jekyll/_config.yml
            Source: /srv/jekyll
       Destination: /srv/jekyll/_site
 Incremental build: disabled. Enable with --incremental
       Jekyll Feed: Generating feed for posts
                    done in 2.409 seconds.
 Auto-regeneration: enabled for '/srv/jekyll'
    Server address:
  Server running... press ctrl-c to stop.

Which looks like:

Screen shot of jekyll new website

Now that the boilerplate is out of the way, I can start personalising it.

Customising the website

Unless you plan on using the default theme, DO NOT start modifying any config files or templates yet as some themes may use different config or layout structure so you may end up losing any progress you make.

Changing Theme/Layout

I regretted starting to customise the layout of the default theme minima and the config as I had to scrap many of the settings when I installed a new theme. I chose a free theme contrast which includes a dark variant that I like and I used this as my starting point. Although the customisation process may be different between themes, it is likely to follow similar steps:

1. Installing your theme

The contrast theme had the option to use a “remote” install (not copying all the layouts) which is documented here.

Alternatively, some themes would require you to start with their template repository.

Some features may require you to install Jekyll plugins which can be done by changing the jekyll_plugins section in your Gemfile.

2. Configuring your site

Edit the _config.yml file with your own settings. In the cast of contrast, it came with good documentation for the options available.

In some cases, I had to update Gemfile and edit or overload layout files.

3. Adjusting layout assets

Depending on how you installed your theme, you will have to either:

Jekyll will search for _layouts and _includes in your base folder first, which allows any file from themes to be simply overridden by creating a copy in your base folder.

Adding new posts

This was incredibly easy, simply add a new file in _posts folder, either as markdown or HTML. You simply need to add the Jekyll Front Matter (top YAML section between the two ---). Here is a simple example of an article in markdown:

layout: post
title:  "Making this website with Jekyll"
date:   2019-06-23 13:26:01 +0100
categories: [jekyll, docker]
tags: [jekyll, website, docker, favicon]

A walk-through of how I made this easy to maintain but featureful static website using **Jekyll** based on a **Docker** development workflow. Although this required some ramp-up to getting started, making changes is trivial. All the steps outlined below should be easy to follow and include a brief explanation to help you learn!

And now for another paragraph...

Unless otherwise specified in the excerpt_separator setting of the configuration file, the first paragraph will be generally used as the excerpt when generating article list pages.

Adding or updating pages

Both the default minima theme and the contrast themes both included a default index page which was easily customisable. In my case, I chose to enable the pagination version which I felt provided a better experience and also rendered an article excerpt in the listing.

I also wanted to add a couple of extra pages, such as an about, search and contact page. This was even easier than adding a post, simply add the Front Matter as before, followed by your HTML or markdown content. For example:

layout: page
title: About
permalink: /about/

Hey, here is a page about me!

In addition, I had to add the page to the navigation section of my _config.yml in order for it to be listed in my navigation.

Adding dynamic components

The drawback of having a statically generated website is that you are unable to have dynamic content such as comments, search or forms.

The benefit of statically generated websites is that you do not have to! Why not rely on external services to provide this for you?

I was able to easily find and implement three different services that allowed me to have comments, search and a contact form within half an hour!


My theme contrast came with a _config.yml with a comment section providing support for two options out of the box: disqus and isso. I chose to use disqus as it came with a hosted free tier package as opposed to isso which required self-hosting.

After registering on and creating a “site” with the short name “evdev”, I simply updated the disqus option of the _config.yaml to “evdev” and that was all.

Google offers a free service called Custom Search Engine which will automatically crawl your website and build a search index for it. You can then expose this as a search form on your own website.

You will need to first register your website and set a URL matching pattern after which you will be given the embed code. After that, I just added a search.html page as follows:

layout: page
title: Search this site
permalink: /search/
<script async src=""></script>
<div class="gcse-search"></div>


For my contact form, I decided to use formspree as it is free and is ultimately just a form.

While you can pay for better integration where the user feels like they never left your website, I was happy with the free tier which cases the user to be redirected to formspree to pass a captcha and be shown a branded message before being given a link to return to my website.

I simply added a contact.html as follows:

layout: page
title: Contact
permalink: /contact/

<form action="" method="POST">
    <input type="hidden" name="_subject" value="EvDev Contact Form">

    <label for="name">Name: </label>
    <input type="text" name="name" required>

    <label for="email">Email: </label>
    <input type="email" name="_replyto" required>

    <label for="comments">Comments: </label>
    <textarea name="comments" required></textarea>
    <input type="submit" value="Submit">


Overall Jekyll proved to be a very easy tool to get started with, and even though documentation was easily accessible, most of the time I didn’t feel that I needed it. The fact that at the end of the process, I’m just dealing with static assets made it much easier to host and not have to worry about databases or keeping my website up-to-date.

My biggest pain-points during the whole process were as a result of my Docker powered workflow, or more specifically with my windows powered setup. The main issues were:

comments powered by Disqus