Deploy Jekyll to Kubernetes

Topics: Jekyll, Kubernetes

This note collects configuration for packaging and deploying a Jekyll site on Kubernetes.

Rackup

We install rackup in Gemfile to have it serve our content. I tried using jekyll serve but that modifies the site.url setting which we don’t want.

gem "rack-contrib"
gem "rack-rewrite", "~> 1.5.0"
gem "rack-ssl", "~> 1.4.1"

Rackup also requires a config.ru configuration file.

Bundler setup

Installing gems into the vendor directory for better CI caching requires excluding this directory from the build path in _config.yml.

include:
  - /images
exclude:
  - /src
  - /Gemfile
  - /Gemfile.lock
  - /package.json
  - /yarn.lock
  - /yarn-error.log
  - /node_modules
  - /vendor
  - /tailwind.js
  - /webpack.config.js
  - /postcss.config.js
  - /README.md

Docker setup

Rake tasks

PROJECT_NAME = File.basename(Dir.getwd)

...

namespace :docker do
  DOCKER_IMAGE = PROJECT_NAME

  desc "Build Docker image"
  task :build do
    sh "docker build -t #{DOCKER_IMAGE} ."
  end

  desc "Run container locally"
  task :run do
    sh "docker run --rm -p 5000:5000 -e DEV_ENV=true #{DOCKER_IMAGE}"
  end
end

Dockerfile

FROM ruby:2.6.5

RUN apt-get update -qq && \
  apt-get install -yq build-essential nodejs
RUN gem install bundler

RUN mkdir /app
WORKDIR /app

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install

ADD . /app

RUN bundle exec jekyll build

EXPOSE 5000
CMD ["bundle", "exec", "rackup", "-o", "0.0.0.0", "-p", "5000"]

We want to prevent unnecessary files included in the image by providing a sensible .dockerignore file.

/.git/
/.sass-cache/
/bin/
/k8s/
/vendor/
/node_modules/

Rack configuration

…

Kubernetes deployment

We have to create a deploy token named gitlab-deploy-token (under “Settings”, “Repository”) that will automatically become available during the CI run.

For deploy previews, we need to define the REVIEW_DOMAIN in the project’s CI variables.