/ DOCKERJEKYLL
 / 10.59350/ncxkh-drg66

Serving a Jekyll Blog with Docker

By DXR (Flickr Front de Seine) CC BY-SA 2.0 https://creativecommons.org/licenses/by-sa/2.0, via Wikimedia Commons

Well, this might be a catchy title. But what we are going to do, is to put the Jekyll artifacts into a Docker image and get a completely self-contained website.

Jekyll, what? Artifacts?

Ok, let’s start from the very beginning. Jekyll is a static website generator. This blog is run by Jekyll. That means, we do only have to edit markdown files and a ruby program generates everything around that and transforms the posts into a website. Usually this is a task done by CMS, such as TYPO3 or Wordpress, but we don’t need a complete PHP and MySQL-based solution for that.

The artifacts are generated by Jekyll upon deployment or locally and consist of a static HTML website with all assets, such as images, stylesheets and so on, included.

The main advantage is (as stated above), we only need a dumb webserver to run this, no JVM, no PHP interpreter, no Ruby, no …

Building It

So, our task here is, to generate the HTML files and put everything into a Docker Container, that includes an Apache Webserver. And that is basically everything we have to do in our Dockerfile:

FROM ruby:2.3 as build

ENV JEKYLL_ENV: production
WORKDIR /usr/src/app

COPY . /usr/src/app

RUN bundle install && \
    bundle exec jekyll build -d public

FROM httpd:2.4-alpine

COPY --from=build /usr/src/app/public/ /usr/local/apache2/htdocs/

This Dockerfile is quite interesting, even as it is really, really short. It starts building the Jekyll stuff with the ruby:2.3 image, that is later referenced as build. Jekyll generates its arfifacts and puts them into the directory public, as we defined it in the command bundle exec jekyll build -d public.

After the artifacts are built, we refer to another image. the ‘official’ Apache Webserver image httpd:2.4-alpine. I am using the alpine version here, because it results in much smaller Docker images. In the lat line, we copy the public directory from the formerly generated ruby-based image into the new httpd-image in the desired root-directory for the Apache Webserver.

And that’s it!

When we are building that with docker build -t lab . a self-contained Blog with a bundled Webserver is created. The image, that is only 32MB small, may be run with docker run -it --rm --name lablab -p 9878:80 lab and when opening http://localhost:9878 in the browser, the blog is served!

Y U no nginx?

You might ask. One does not simply use nginx, but just to add the same for nginx:

FROM ruby:2.3 as build

ENV JEKYLL_ENV: production
WORKDIR /usr/src/app

COPY . /usr/src/app

RUN bundle install && \
    bundle exec jekyll build -d public

FROM nginx:1.13-alpine

COPY --from=build /usr/src/app/public/ /usr/share/nginx/html/

And the answer to the question in the headline is: I have no experience using nginx and trying to use the alpine version of the nginx image resultet in the error, that the desired platform is not supported (no matching manifest for linux/amd64 in the manifest list entries), that means, at the time of the writing the desired image has not been available, because the Docker Hub images are eventually consistent, due to different build server environments and capabilities.