Posted by & filed under DevOps, Docker, Web development.

Jekyll is a static site generator written in Ruby and designed to be a simple way to create a blog-like website. It’s what GitHub uses for Pages, which means you can also host your Jekyll-powered blog there for free. Static HTML pages load fast, there’s no database or programming involved (unless you add your own Javascript or other plugins), and no hosting company to deal with.

There is one caveat, though — Jekyll can be a bit difficult to install, since it does have quite a few Ruby dependencies and it also unfortunately requires Node.js to support a non-optional plugin.

Use Docker

On OS X, boot2docker is the preferred way to use Docker. In order to make sharing folders with Docker containers easier, we use the special Guest Additions version of boot2docker. Because there may be some security implications with this version and the fact that it’s a temporary fix until folder sharing works better, we opted to create a separate boot2docker profile that we only use when folder sharing is required. See Multiple Boot2docker Profiles On Mac OS X for more details.

To begin, we’ll create a directory that will be the root of the shared volume:

> mkdir ~/Documents/docker_share

Next, we’ll make sure the boot2docker virtual machine is stopped, and then add the shared volume.

> boot2docker down
> VBoxManage sharedfolder add [BOOT2DOCKER VM NAME] --name home --hostpath ~/Documents/docker_share --automount

Replace [BOOT2DOCKER VM NAME] with the name of the boot2docker virtual machine. If you’re using a different profile, make sure you use the virtual machine’s name for that profile. You can find this by running boot2docker info and looking at the value of Name.

Bring the virtual machine back up:

> boot2docker up

The Guest Additions virtual machine will automatically mount the shared folder to /Users. You should now be able to add and remove files from ~/Documents/docker_share outside of the virtual machine and have them visible *inside* the virtual machine (and vice versa).

> boot2docker ssh ls /Users

Setting up Jekyll

The easiest way to setup Jekyll is to grab our prebuilt image via docker pull loopscience/jekyll-base. Alternatively, you can create your own image by building the following Dockerfile:

FROM centos:latest

RUN yum -y install epel-release && yum -y install ruby ruby-devel make gcc nodejs npm
RUN gem install jekyll

Note: If you’ve created your own image, replace all further instances of loopscience/jekyll-base with your own image.

Let’s create a new Jekyll site:

> docker run --rm -v /Users:/mnt/share loopscience/jekyll-base jekyll new mysite

Here’s a rundown of what we just did:
--rm – remove the docker container after the command completes

-v /Users:/mnt/share – mount the /Users directory from the virtual machine in the Docker container as /mnt/share

loopscience/jekyll-base – use the loopscience/jekyll-base image

jekyll new mysite – run jekyll inside the Docker container with the new option to create the site named mysite

If no errors display, you should now have a Jekyll site in ~/Documents/docker_share/mysite. Let’s check:

> ls ~/Documents/docker_share/mysite
_config.yml	_layouts	_sass		css		index.html
_includes	_posts	feed.xml

If you see a similar file list, everything should’ve worked as expected. Now we can run the jekyll build command to generate the actual HTML for the site. We’ll provide a destination -d /mnt/share/mysite_published and the source -s /mnt/share/mysite so we don’t have to be concerned about entering the right directory inside the container.

> docker run --rm -v /Users:/mnt/share loopscience/jekyll-base jekyll build -d /mnt/share/mysite_published -s /mnt/share/mysite
Configuration file: /mnt/share/mysite/_config.yml
            Source: /mnt/share/mysite
       Destination: /mnt/share/mysite_published

Now that the site has been built, we can run jekyll serve to view the site in our browser. But first, we need to determine boot2docker’s IP address:

> boot2docker ip
The VM's Host only interface IP address is:

Now that we know the IP address, we can run Jekyll’s local webserver. We’ll need to provide one extra option to Docker that publishes the port Jekyll’s webserver will be running on:

> docker run --rm -v /Users:/mnt/share -p 4000:4000 loopscience/jekyll-base jekyll serve -d /mnt/share/mysite_published -s /mnt/share/mysite
Configuration file: /mnt/jekyll/mysite/_config.yml
            Source: /mnt/jekyll/mysite
       Destination: /mnt/jekyll/mysite_published
 Auto-regeneration: enabled for '/mnt/jekyll/mysite'
Configuration file: /mnt/jekyll/mysite/_config.yml
    Server address:
  Server running... press ctrl-c to stop.

Open your web browser to the IP address provided by boot2docker ip followed by :4000. For example: You should be presented with the default Jekyll home page.

Screen Shot 2014-09-19 at 5.35.40 PM


Modify ~/Documents/docker_share/mysite as desired, restarting jekyll serve to see the latest changes.

Publishing to GitHub Pages

One super-nice aspect of GitHub Pages is that it allows us to host our Jekyll site for free. Once you’ve created a repository in GitHub, a branch named gh-pages will serve any HTML content you provide (you’ll need to create this if it doesn’t exist).

One configuration change we need to make before publishing to GitHub is inside _config.yml. Because GitHub Page project URLs are in the form of, we need to tell Jekyll our baseurl is actually /project instead of /.

Edit ~/Documents/share/mysite/_config.yml and change baseurl: "" to baseurl: "/[PROJECT NAME]". Just remember, if you try to load the Jekyll site locally now, you’ll need to append the same /[PROJECT NAME] to the URL.

After making that change, pushing our recently created Jekyll site is pretty easy:

> cd ~/Documents/share/mysite_published
> git init
> git checkout --orphan gh-pages
Switched to a new branch 'gh-pages'
> git add -A
> git commit

Here’s what we just did:
1. Initialized a new git repository
2. Created an orphaned branch since we don’t yet have a master branch
3. Add all files and commit

Add the remote GitHub repository:

> git remote add origin https://[GITHUB USERNAME][GITHUB USERNAME]/repository

Finally, push the new branch, and set upstream reference

> git push origin gh-pages -u

Now that we’ve setup the repository and upstream reference, subsequent pushes are much simpler:

> git commit -a
> git push origin gh-pages

Pushing changes can take between 10 and 15 minutes, so when you browse to http://[GITHUB USERNAME] you may see a 404 page or old content while the page is being updated.


Sign up for Turret.IO — the only data-driven marketing platform made specifically for developers.

Leave a Reply

Your email address will not be published. Required fields are marked *