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:
- You have an account and are logged into console.scaleway.com
- You have configured your SSH Key
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.
Start with the installation of our development platform.
1 . Before you can install the tool itself, you need to install ruby
together with make
, tree
and the build-essential
package
sudo apt-get install ruby ruby-dev make build-essential tree git-core
2 . Once the installation has finished, create a user to run Jekyll and switch into the account of the user
adduser jekyll
su jekyll
3 . Before launching the installation, 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/gems
export 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 like as following
jekyll new www
The command will generate the following files, enter the www
directory by typing cd www
.
8 . Once you are in the directory, 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.
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 . Once this is done, login as the git
user and create the repository
su git
mkdir -p /home/git/scaleway-web.git
cd /home/git/scaleway-web.git
git init --bare
7 . The following message will appear if everything went well
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.
8 . 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.git
TMP_DIRECTORY=/tmp/scaleway-blog
PUBLIC_WWW=/var/www/html
git clone $GIT_REPO $TMP_DIRECTORY
pushd $TMP_DIRECTORY
bundle exec jekyll build -d $PUBLIC_WWW
popd
rm -rf $TMP_GIT_CLONE
exit
9 . Make the file executable
chmod +x /home/git/scaleway-blog/hooks/post-receive
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/gems
export 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
To push the content from the development system to the production server, running our website, Git uses SSH.
1 . 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 rsa
ssh-copy-id git@<production-server-ip>
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 . To enable the non-interactive shell, create the file no-interactive-login
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
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 init
Initialized empty Git repository in /home/jekyll/www/.git/
2 . Once this is done, add the remote repository
git remote add origin git@5<production-server-ip>:scaleway-blog.git
3 . Before you are able to 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 . Now it is time for the first commit. The -m
parameter represents the comment for the commit
jekyll@jekyll-dev:~/www$ git commit -m "Initial commit."
5 . 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 .gitignore
create mode 100644 404.html
create mode 100644 Gemfile
create mode 100644 Gemfile.lock
create mode 100644 _config.yml
create mode 100644 _posts/2018-05-16-welcome-to-jekyll.markdown
create mode 100644 about.md
create mode 100644 index.md
6 . Finally, push the content to our production server
git push origin master
7 . An output like the following is displayed
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.git
remote: Configuration file: /tmp/scaleway-blog/_config.yml
remote: Source: /tmp/scaleway-blog
remote: Destination: /var/www/html
remote: Incremental build: disabled. Enable with --incremental
remote: Generating...
remote: done in 0.702 seconds.
remote: Auto-regeneration: disabled. Use --watch to enable.
remote: ~/scaleway-blog.git
* [new branch] master -> master
Jekyll provides a built-in web server so the site can run during development directly on the development server.
1 . To run it, type the following command
jekyll serve --detach
2 . An output like the following appears
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.
3 . Once the server is started, use tree
again, to see what happened since Jekyll is 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.
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 settings
title: Your awesome title
email: your-email@example.com
description: >- # this means to ignore newlines until "baseurl:"
Write an awesome description for your new site here. You can edit this
line in _config.yml. It will appear in your document head meta (for
Google search results) and in your feed.xml site description.
baseurl: "/blog" # the subpath of your site, e.g. /blog
url: "http://myblog.com" # the base hostname & protocol for your site, e.g. http://example.com
twitter_username: jekyllrb
github_username: jekyll
# Build settings
markdown: kramdown
theme: minima
plugins:
- 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 Matters: Jeykill 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 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 ---
A directory _includes
, that contains all elements of the site that are being used on each page:
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>
</li>
</ul>
</nav>
</div>
</aside>
<header>
<h1><a href="{{ site.baseurl }}">{{ site.title }}</a></h1>
</header>
A _layouts
directory that 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 }}
1 . To have a separate folder for our blog, we create a directory blog
and put the following file in it:
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="{% raw %}{{ "/feed.xml" | prepend: site.baseurl }}">via RSS</a></p>
2 . A css
folder which should contain only one file:
main.scss
with the following contents:
---
# Layout files to import.
---
@import
"base",
"layout",
"syntax-highlighting"
3 . A _sass
folder, which is also empty and will 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.