Jump toUpdate content

Creating a Jekyll powered website

Reviewed on 10 May 2021 โ€ข Published on 12 July 2018
  • compute
  • cms
  • jekyll

Jekyll is a Ruby based tool to generate static websites from MarkDown files.

This means it generates static HTML files from templates that are served to your visitors like standard HTML files that you have written by yourself.

This makes Jekyll a very lightweight solution in terms of RAM and CPU power as the files have only to be generated once, in difference to a page generated by a server-side language, for example in PHP, that has to be generated for each visitor.

Requirements:

For this tutorial, you need to have two Ubuntu Xenial instances ready, one for the development platform and the other to run the site in production.

Installing Jekyll on the Development Server

Start with the installation of our development platform.

  1. Install ruby, make, tree and the build-essential package.

    sudo apt-get install ruby ruby-dev make build-essential tree git-core
  2. Create a user to run Jekyll and switch into the account of the user.

    adduser jekyllsu jekyll
  3. Edit the .bashrc file to provide the gem packet manager the information to place the Gemโ€™s in the users PATH, to avoid conflicts with system-wide installations.

  4. Open the file and add the following lines at the end of the file.

    # Ruby exports
    export GEM_HOME=$HOME/gemsexport PATH=$HOME/gems/bin:$PATH
  5. Save the file, close your text editor and activate the exports.

    source .bashrc
  6. Once this is done, install Jekyll via gem, together with bundler, which manages Gem dependencies.

    gem install jekyll bundler
  7. Create a new site by using jekyll new command. The new site will be named www. Specify it behind the command and run it as the following:

    jekyll new www

    The command will generate the following files, enter the www directory by typing cd www.

  8. Use tree to get a listing of the files generated by Jekyll:

        .    โ”œโ”€โ”€ 404.html    โ”œโ”€โ”€ about.md    โ”œโ”€โ”€ _config.yml    โ”œโ”€โ”€ Gemfile    โ”œโ”€โ”€ Gemfile.lock    โ”œโ”€โ”€ index.md    โ””โ”€โ”€ _posts        โ””โ”€โ”€ 2018-04-16-welcome-to-jekyll.markdown

These files are not the actual files of your website, but the data used by Jekyll to generate your site.

Installing Git on the Production Server

Jekyll provides a basic web server for testing during development, but its main purpose is to build static HTML files that can be served by a web server.

We use Nginx in our example on the production server.

  1. Start by installing the required software

    sudo apt-get install ruby ruby-dev nginx make build-essential git-core
  2. Run Git on the production server, therefore you have to create โ€˜gitโ€™ user

    sudo adduser git
  3. Answer the questionnaire and set a password for the user.

  4. Now prepare the web root for the site. Start by removing the default index.html file that has been generated by Ubuntu

    sudo rm /var/www/html/index.nginx-debian.html
  5. Set the ownership of the web directory so git can update it

    sudo chown git:www-data /var/www/html
  6. Login as the git user and create the repository

    su gitmkdir -p /home/git/scaleway-web.gitcd /home/git/scaleway-web.gitgit init --bare

    If the operation is successfully youโ€™ll see the following output:

    Initialized empty Git repository in /home/git/scaleway-web.git/

    To launch the automatic regeneration of our site once we have pushed updates to Git, use Git Hooks.

    These are scripts that are used by Git to trigger actions at certain points in gitโ€™s execution.

    Git stores these scripts in the directory hooks and we will use the post-receive hook to regenerate our site when we push it to Git.

  7. Create the file post-receive in the hooks directory and put the following content in it

    #!/usr/bin/env bash
    GIT_REPO=$HOME/scaleway-blog.gitTMP_DIRECTORY=/tmp/scaleway-blogPUBLIC_WWW=/var/www/html
    git clone $GIT_REPO $TMP_DIRECTORYpushd $TMP_DIRECTORYbundle exec jekyll build -d $PUBLIC_WWWpopdrm -rf $TMP_GIT_CLONE
    exit
  8. Make the file executable.

    chmod +x /home/git/scaleway-blog/hooks/post-receive

Installing Jekyll on the Production Server

To build the site, you also need an installation of Jekyll on the production server.

On this server, Jekyll will run under our git user.

As on the development instance, edit the .bashrc file to provide the gem packet manager the information to place the Gemโ€™s in the users PATH to avoid conflicts with system-wide installations.

  1. Open the file .bashrc and add the following lines at the end of the file

    # Ruby exports
    export GEM_HOME=$HOME/gemsexport PATH=$HOME/gems/bin:$PATH
  2. Save the file, close your text editor and activate the exports

    source .bashrc
  3. Continue with the installation of Jekyll on the production server

    gem install jekyll bundler jekyll-feed jekyll-seo-tag minima

Creating an SSH Key for Data Transfer

To push the content from the development system to the production server, running our website, Git uses SSH.

Create an SSH key for our jekyll user so it can push contents to the production server.

Run the following commands on our development server

ssh-keygen -t rsassh-copy-id git@<production-server-ip>

Disabling Full SSH Login on the Git Shell

For security reasons we configure a non-interactive shell, disabling access to the serverโ€™s console via SSH, but allowing to use git commands to manage existing repositories.

Make sure to run the following commands as git user on the production server.

  1. Start by making a git-shell-commands folder, which is required for git-shell to work properly.

    mkdir -p /home/git/git-shell-commands
  2. Create the file no-interactive-login to enable the non-interactive shell, and open it with Nano.

    nano /home/git/git-shell-commands/no-interactive-login
  3. Put the following information in the file.

    #!/usr/bin/env bash
    printf '%s\n' "Welcome $USER. Interactive sessions are disabled for security reasons."
    exit 128
  4. Save the file and make it executable.

    chmod +x /home/git/git-shell-commands/no-interactive-login
  5. Return to the root account by typing exit.

  6. Configure the user to use the git-shell

    sudo usermod -s $(which git-shell) git

Configuring Git on the Development Server

To be able to use Git to manage the files between both, development and production instances, it has also to be installed on the development instance.

Run the following commands with the jekyll user.

  1. Change into the Jekyll directory (www) and initialize the Git repository.

    jekyll@jekyll-dev:~$ cd www/jekyll@jekyll-dev:~/www$ git initInitialized empty Git repository in /home/jekyll/www/.git/
  2. Add the remote repository.

    git remote add origin git@5<production-server-ip>:scaleway-blog.git
  3. Before you push content to the production system, you have to tell Git which files it should push. We want to use all the files in our directory

    git .
  4. Make your first commit. The -m parameter represents the comment for the commit:

    jekyll@jekyll-dev:~/www$ git commit -m "Initial commit."

    A list of the files that have been modified will appear

    [master (root-commit) d9621c8] Initial commit.8 files changed, 223 insertions(+)create mode 100644 .gitignorecreate mode 100644 404.htmlcreate mode 100644 Gemfilecreate mode 100644 Gemfile.lockcreate mode 100644 _config.ymlcreate mode 100644 _posts/2018-05-16-welcome-to-jekyll.markdowncreate mode 100644 about.mdcreate mode 100644 index.md
  5. Push the content to our production server

    git push origin master

    An output like the following displays:

    Counting objects: 4, done.Compressing objects: 100% (4/4), done.Writing objects: 100% (4/4), 359 bytes | 0 bytes/s, done.Total 4 (delta 2), reused 0 (delta 0)remote: /tmp/scaleway-blog ~/scaleway-blog.gitremote: Configuration file: /tmp/scaleway-blog/_config.ymlremote:             Source: /tmp/scaleway-blogremote:        Destination: /var/www/htmlremote:  Incremental build: disabled. Enable with --incrementalremote:       Generating...remote:                     done in 0.702 seconds.remote:  Auto-regeneration: disabled. Use --watch to enable.remote: ~/scaleway-blog.git [new branch]      master -> master

Running Jekyll During Development Locally

Jekyll provides a built-in web server so the site can run during development directly on the development server.

  1. Enter the command:

    jekyll serve --detach

    An output like the following displays:

        Configuration file: /home/jekyll/www/_config.yml                Source: /home/jekyll/www          Destination: /home/jekyll/www/_site    Incremental build: disabled. Enable with --incremental        Generating...                    done in 1.715 seconds.    Auto-regeneration: disabled when running server detached.      Server address: http://127.0.0.1:4000/      Server detached with pid '15424'. Run `pkill -f jekyll' or `kill -9 15424' to stop the server.
  2. Use tree again, to see what happened since Jekyll started.

        .    โ”œโ”€โ”€ 404.html    โ”œโ”€โ”€ about.md    โ”œโ”€โ”€ _config.yml    โ”œโ”€โ”€ Gemfile    โ”œโ”€โ”€ Gemfile.lock    โ”œโ”€โ”€ index.md    โ”œโ”€โ”€ _posts    โ”‚ย   โ””โ”€โ”€ 2018-04-16-welcome-to-jekyll.markdown    โ””โ”€โ”€ _site        โ”œโ”€โ”€ 404.html        โ”œโ”€โ”€ about        โ”‚ย ย  โ””โ”€โ”€ index.html        โ”œโ”€โ”€ assets        โ”‚ย ย  โ”œโ”€โ”€ main.css        โ”‚ย ย  โ””โ”€โ”€ minima-social-icons.svg        โ”œโ”€โ”€ feed.xml        โ”œโ”€โ”€ index.html        โ””โ”€โ”€ jekyll            โ””โ”€โ”€ update                โ””โ”€โ”€ 2018                    โ””โ”€โ”€ 04                        โ””โ”€โ”€ 16                            โ””โ”€โ”€ welcome-to-jekyll.html

Jekyll has generated a folder _site, containing the actual HTML files of the website.

Configuring your Site

Jekyll uses different configuration files to generate the static content of the site automatically.

A file _config.yml is available in the main directory. By default its minimum content should look like this

# Site settingstitle: Your awesome titleemail: your-email@example.comdescription: >- # this means to ignore newlines until "baseurl:"Write an awesome description for your new site here. You can edit thisline in _config.yml. It will appear in your document head meta (forGoogle search results) and in your feed.xml site description.baseurl: "/blog" # the subpath of your site, e.g. /blogurl: "http://myblog.com" # the base hostname & protocol for your site, e.g. http://example.comtwitter_username: jekyllrbgithub_username:  jekyll
# Build settingsmarkdown: kramdowntheme: minimaplugins:- jekyll-feed
# Exclude from processing.# The following items will not be processed, by default. Create a custom list# to override the default setting.# exclude:#   - Gemfile#   - Gemfile.lock#   - node_modules#   - vendor/bundle/#   - vendor/cache/#   - vendor/gems/#   - vendor/ruby/

It is possible to edit it towards your requirements.

To customize the layout of the pages, it is possible to build a template by creating the following directories and files:

Front Matter:

  • Jeykyll will interpret all files starting with a YAML Front Matter as a special file. The front matter must be the first thing in a file and
  • It must take the form of valid YAML set between triple-dashed lines. Here is a very basic example:
  ---  layout: post  title: Managing site content with Jekyll  ---

The _includes directory contains all elements of the site that are being used on each page. It is composed of:

  • footer.html - The footer of each package.
<footer>  <p>Hosted at <a href="https://scaleway.com">Scaleway</a></p>  <p>    {% if site.github_username %} {% include icon-github.html    username=site.github_username %} {% endif %} {% if site.twitter_username %}    {% include icon-twitter.html username=site.twitter_username %} {% endif %}  </p></footer>
  • head.html - All HEAD metadata.
<head>  <meta charset="utf-8" />  <meta http-equiv="X-UA-Compatible" content="IE=edge" />  <title>    {% if page.title %} {{ page.title }} {% else %} {{ site.title }} {% endif %}  </title>  <meta name="description" content="{{ site.description }}" />  <meta name="viewport" content="width=device-width" /></head>
  • header.html - The navigation and header of your website.
<aside>  <div class="container">    <nav>      <ul>        {% for page in site.pages %} {% if page.title %}        <li>          <a href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a>        </li>        {% endif %} {% endfor %}        <li><a href='{{ "/blog" | prepend: site.baseurl }}'>Blog</a></li>      </ul>    </nav>  </div></aside>
<header>  <h1><a href="{{ site.baseurl }}">{{ site.title }}</a></h1></header>

The _layouts directory may contain the following files:

  • default.html - The default layout of your website.
<!DOCTYPE html><html>  {% include head.html %}
  <body>    {% include header.html %}    <main>      <article>{{ content }}</article>      {% include footer.html %}    </main>  </body></html>
  • page.html
## layout: default
<h2>{{ page.title }}</h2>
{{ content }}
  • post.html
## layout: default
<h2>{{ page.title }}</h2><time  >{{ page.date | date: "%b %-d, %Y" }}{% if page.author %} โ€ข {{ page.author  }}{% endif %}{% if page.meta %} โ€ข {{ page.meta }}{% endif %}</time>
{{ content }}

Creating the blog

  1. Create a separate directory for your blog. In this tutorial we call it blog.

  2. Enter the following file in the directory:

  • index.html with the following content:

    ## layout: default
    <h4>blog</h4>{% for post in site.posts %}<time>{{ post.date | date: "%b %-d, %Y" }}</time><h3><a href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a></h3>{% endfor %}
    <p>subscribe <a href="{{ "/feed.xml" | prepend: site.baseurl }}">via RSS</a></p>
  1. Create a css folder, which should contain only one file:
  • main.scss with the following contents:

    --- # Layout files to import. --- @import "base", "layout","syntax-highlighting"
  1. Create _sass folder, which should also empty, to contain your style elements:
  • _base.scss - which contains all variables, mixins, and resets

  • _syntax-highlighting.scss - Which can contain the information about the syntax highlighting for different languages

  • _layout.scss - The layout information for your site

The assets folder contains all statical assets that you want to use on your site, for example, images.

All content of the site is located in the directory _posts. To create a new blog post, create a new file in the format YYYY-MM-DD-name-of-post.markdown.

Jekyll uses the Liquid templating language to process templates. So you can place different variables in your files that will be replaced automatically with different contents.

More information on the directory structure of Jeykill is available directly in their documentation.

In this tutorial you have installed a Jekyll development instance to deploy our site and to run it locally on this machine for testing purposes. We have also setup Git to push the site to a production server and to generate it automatically by Jekyll, before it is finally served to our users by Nginx. If you want to learn more about Jekyll, you may read the official documentation.