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.