I have been thinking of making a blog for a while. I wanted to find a blogging platform that was simple, customizable, static content based so that I could host it in GitHub pages, and supported Markdown so that I could easily publish code projects from Jupyter notebooks and R’s knitr. After a bit of searching I decided to go forward with Jekyll which is a Ruby based blogging platform that seems to have the above features.
Why GitHub pages
GitHub provides hosting for static content sites via it’s GitHub pages. This is really convenient as one does not have to bother setting up a production server and the pages are automatically served from a git repository. All you need to do is to push your content into a special repository (more of this below).
What is neat with GitHub pages for Jekyll is that Jekyll based pages can automatically built by GitHub, meaning that the static content is automatically compiled from the Jekyll source files, such as those Markdown files. Given that GitHub was originally built with Ruby On Rails, the famous Ruby based web-application framework, it’s no wonder that GitHub gave the Ruby based Jekyll a special support. However, I ended up not using that neatness due to a missing gem (Ruby library) in the GitHub environment that was required by my custom theme.
Setting up a developer environment
It’s essential to be able to test your site in your local computer. Jekyll is based on Ruby which needs to be installed if you want to compile your blog from the source files. Installing Ruby and learning it’s ecosystem will take some time, so unless you have that ready it is probably the easiest to use Docker instead.
Jekyll has an official docker image that has all the needed components installed. The following instructions will be based on Docker and assumes you have a working Docker installed to your computer and you are using linux. If you are using Windows 10, you can either use the bash shell within Windows or just modify the commands below.
The philosophy behind the Docker commands below is that if we had Ruby environment installed locally,
we could just run commands like
jekyll new or
bundle install to build a new blog or install
Ruby libraries (called gems).
Now instead we will run such commands with
docker run through the container that has the
Ruby environment installed.
Creating the initial jekyll source files with Docker
We will use the official Jekyll Docker image to build the initial source files for
You can find the files created in this section from this repository that I created.
To start, first create a folder for the blog, e.g.
The initial Jekyll blog files can now be created into the
blog folder with
Jekyll Docker image (I used
jekyll/jekyll:3.8) by running:
docker run --rm --volume="$PWD/blog:/srv/jekyll" -it jekyll/jekyll:3.8 \ jekyll new . --skip-bundle
The command mounted your
blog directory to
/srv/jekyll in the container and then created the
blog files with
The source files should now appear in your
Additional info about the command used above can be found from here.
It may be beneficial to open an interactive shell to the container to test the different commands, for instance to open an interactive bash shell type:
docker run --rm --volume="$PWD/blog:/srv/jekyll" -it jekyll/jekyll:3.8 \ bash
Now you can check the options for
jekyll new with
jekyll new --help (note that in the first time
it will install bunch of gems).
Some files that we will be needing are
Gemfile which lists the gems (Ruby libraries) that your project will
_config.yml which is the Jekyll site configuration file.
Running the server locally with Docker
The fastest way to run the server is to change directory to the
(that contains the source files) and type:
docker run --rm --volume="$PWD:/srv/jekyll" -p 4000:4000 -it jekyll/jekyll:3.8 \ bash -c "bundle install && bundle exec jekyll serve -H 0.0.0.0"
You should see information about the server staring. If not, make sure you are in the same folder
where you have the source files created above (the
blog folder in this example).
Now you should have your blog running in
localhost:4000 so go ahead and type that to your
browser’s address bar to test.
Details of the arguments to
docker run can be found from here.
While the server is running you can edit the different files to see their effect.
For instance you can modify the
about.md file and see how the About page is changed after you
save the changes.
Exceptions are the files
Gemfile that require restarting the server.
Speeding up the starting of the server
The above process always reinstalls the needed gems to the container based on the official image.
A more efficient way is to first create an image that has the needed gems and then use that image.
This will actually speed up all the other commands too.
Assuming we are in the
blog folder, type:
docker run --name blog_server --volume="$PWD:/srv/jekyll" -it jekyll/jekyll:3.8 \ bundle install
Notice that we removed the
--rm argument which would remove the container after execution. Instead
--name to give the container a name
blog_server. Now typing
docker ps -a
should show you a container with that name. It has all the gems installed
and the final step is to make an image of it with
docker commit blog_server blog_server
Now we have an image called
blog_server that is based on the official image and has all the needed
You can see this image listed by typing
The server can now be ran using our new image with
docker run --rm --volume="$PWD:/srv/jekyll" -p 4000:4000 -it blog_server \ bundle exec jekyll serve -H 0.0.0.0
You will notice that server starts in an instant. As long as you keep the image in your computer you can use it to serve the blog. If you at some point update your bundle (Gemfile) you can recreate the image with the steps above.
Customizing the blog
The first thing in customizing the blog is to choose a theme.
If you are planning to host in GitHub with automatic compilation, you can choose the theme from
multiple options or even use custom themes via the
To test locally you need to replicate the GitHub Ruby environment.
Luckily GitHub makes this really easy, you just need to have
gem "github-pages", group: :jekyll_plugins
Gemfile and remove the
gem "jekyll" line.
This will install all the gems in your local environment that are provided at GitHub.
I had already chosen a theme that was not in the list of GitHub supported themes and
unfortunately depended on a gem called
jekyll-archives that was not available in the GitHub Ruby
This caused the post tags to silently disappear from the posts in compilation (luckily I noticed it).
I figured the safest and easiest way forward at this stage would be to just build the pages locally,
and push the compiled static pages to GitHub.
That way I wouldn’t have to worry about what’s available in the GitHub Ruby environment and what’s
Of course this means more manual work for me, but not that much.
I followed the quick start instructions of the theme to edit my source files.
Hosting in GitHub
The last step is to have GitHub host the compiled pages. GitHub has made this really
You only need to create a git repository with a special name
<username>.github.io and all the
static content you push to it’s
master branch will be available at
A small nuisance in my case is that I need to manually compile the pages and then push the compiled pages to GitHub. To compile the pages with Docker one can either:
docker run --volume="$PWD:/srv/jekyll" -it jekyll/jekyll:3.8 \ jekyll build
or use the
blog_server image created above
docker run --volume="$PWD:/srv/jekyll" -it blog_server \ jekyll build
The compiled pages are now found from the
The contents of this folder need to be committed to the master branch of the
repository and pushed.
To automate this I slightly modified the build command to place the files directly to the
local clone of the
docker run -v="$PWD:/srv/jekyll" -v="path/to/github_repo:/srv/site" -it blog_server \ jekyll build -d /srv/site
Now the compiled static files are automatically placed to the local
folder. After committing and pushing you should see your blog appearing at