Minimal Mistakes テーマの Jekyll 環境を Docker 化する
久々にブログシステムの環境をアップグレードしたメモです。
はじめに
このサイトでは 過去の記事 にあるように、Minimal Mistakes という Jekyll のテーマを利用しています。2 年とちょっと前 には Gem 化された Minimal Mistakes のパッケージを使って当時の最新バージョンにアップグレードしたのですが、それから時間が経過して Minimal Mistakes も随分とバージョンが進んでいたので、久々にアップグレードをすることにしました。
なお今回は単にアップグレード・マイグレーションをするだけに留まらず、Ruby のバージョンを含めてブログシステムの環境を安定したものにすることを目的として Docker ベースの環境への移行も合わせて実現することにしました。
Jekyll 環境の Docker 化
まずは Jekyll の環境を Docker 化するところから始めます。
Docker イメージの構築
Jekyll と Docker というと、例えば Jekyll Docker など既にいくつかの Dockerfile / Docker イメージが存在していますが、以前に Gem 化された Minimal Mistakes で用意した Gemfile
を利用することを前提に、今回は自前で Docker イメージを作ることにします。
# Gemfile の例
source 'https://rubygems.org'
gem 'jekyll', '3.8.5'
gem 'minimal-mistakes-jekyll', '4.16.4'
# ブログシステムで必要とするプラグインを以下に記述する
# group :jekyll_plugins do
# gem 'jekyll-archives'
# end
Docker イメージには以下の 3 つのみを含めることにし、実際のブログサイトに関わる各種リソースや設定 (_config.yml
など) は含めないことにします。
- Ruby
- Jekyll
- Minimal Mistakes
よって、Dockerfile
は次のようになります。
FROM ruby:2.6.3-stretch
COPY Gemfile /work/Gemfile
RUN set -ex \
&& apt-get update \
&& apt-get install -y \
locales \
locales-all \
&& locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
RUN set -ex \
&& cd /work \
&& bundle install \
&& rm -rf /root/.bundle/cache
上記では、ベースイメージに Docker official の Ruby イメージ ruby:2.6.3-stretch
(Debian ベース) を利用していますが、ここは slim イメージでも (build-essential を apt-get install
する必要がありますが) 問題ありません。
Docker コンテナでの jekyll の実行
Jekyll / Minimal Mistakes の Docker イメージが構築できたところで、次はそのイメージを使って Jekyll の各種サブコマンドを実行してみましょう。
例えば、手元の環境において執筆中の記事を Web ブラウザ上で確認したいのであれば、以下のように jekyll serve
を Docker コンテナ上で実行します。
# カレントディレクトリに _config.yml などがあることを想定している
docker run --rm -it --name <コンテナ名> \
-v $PWD/_config.yml:/work/_config.yml \
-v $PWD/index.html:/work/index.html \
-v $PWD/_data/:/work/_data/ \
-v $PWD/_posts/:/work/_posts/ \
-v $PWD/_site/:/work/_site/ \
-v $PWD/images/:/work/images/ \
-p 4000:4000 \
-w /work \
<イメージ名> \
bundle exec jekyll serve -H 0.0.0.0
実際に GitHub Pages などで公開するための HTML その他を出力したいのであれば、以下のように jekyll build
を実行します。docker run
コマンドの -e
(--env
) オプションで JEKYLL_ENV=production
の環境変数を設定しているのがポイントですね。
docker run --rm -it --name <コンテナ名> \
-v $PWD/_config.yml:/work/_config.yml \
-v $PWD/index.html:/work/index.html \
-v $PWD/_data/:/work/_data/ \
-v $PWD/_posts/:/work/_posts/ \
-v $PWD/_site/:/work/_site/ \
-v $PWD/images/:/work/images/ \
-w /work \
-e JEKYLL_ENV=production \
<イメージ名> \
bundle exec jekyll build
なお、これらのコマンドを毎回手で手で打つのは辛いので、以下のような Makefile
を用意しておけば、 make jekyll-serve
, make jekyll-build
といったコマンドをを打つだけで事を済ませられるようになります。
DOCKER = docker
DOCKER_IMAGE = minimal-mistakes-jekyll
DOCKER_CONTAINER = minimal-mistakes-jekyll
.PHONY: docker-build jekyll-build jekyll-serve
docker-build:
mkdir -p tmp
cp Gemfile Dockerfile tmp/
docker build tmp/ -t $(DOCKER_IMAGE)
jekyll-serve:
docker run --rm -it --name $(DOCKER_CONTAINER) \
-v $$PWD/_config.yml:/work/_config.yml \
-v $$PWD/index.html:/work/index.html \
-v $$PWD/_data/:/work/_data/ \
-v $$PWD/_posts/:/work/_posts/ \
-v $$PWD/_site/:/work/_site/ \
-v $$PWD/images/:/work/images/ \
-p 4000:4000 \
-w /work \
$(DOCKER_IMAGE) \
bundle exec jekyll serve -H 0.0.0.0
jekyll-build:
docker run --rm -it --name $(DOCKER_CONTAINER) \
-v $$PWD/_config.yml:/work/_config.yml \
-v $$PWD/index.html:/work/index.html \
-v $$PWD/_data/:/work/_data/ \
-v $$PWD/_posts/:/work/_posts/ \
-v $$PWD/_site/:/work/_site/ \
-v $$PWD/images/:/work/images/ \
-w /work \
-e JEKYLL_ENV=production \
$(DOCKER_IMAGE) \
bundle exec jekyll build
Minimal Mistakes のアップグレード
直近まで利用していた Minimal Mistakes のバージョンは 4.9.1 で、そこから最新の 4.16.4 まではかなりのリリースが積み重なっており、_config.yml
その他のファイルのマイグレーションが必要でした。
Quick-Start Guide を消す
Minimal Mistakes において、ページ上部 (右上) のメニュー表示は _data/navigation.yml
の内容に基づいて作られるのですが、このファイルが存在しないと、Quick-Start Guide へのリンクが表示されてしまいます。
以前は main:
とだけ書かれた内容のファイルを _data/navigation.yml
として置いておけば十分でした。しかし、いつのバージョンからか main:
と書くだけでは不十分で、main: []
と明示的に空配列まで記述しなければならなくなりました (空配列がないと Quick-Start Guide が表示されてしまう)。
Author リンクの記述
著者情報のエリアに表示される各種 Web サービスへのリンクの設定方法が、#1581 の変更によって変わりました 。具体的には、_config.yml
に以下のような書式で記述します。関連するドキュメントは こちら。
author:
links:
- label: "Email"
icon: "fas fa-fw fa-envelope-square"
url: mailto:your.name@email.com
- label: "Website"
icon: "fas fa-fw fa-link"
url: "https://your-website.com"
- label: "Twitter"
icon: "fab fa-fw fa-twitter-square"
url: "https://twitter.com/username"
- label: "Facebook"
icon: "fab fa-fw fa-facebook-square"
url: "https://facebook.com/username"
- label: "GitHub"
icon: "fab fa-fw fa-github"
url: "https://github.com/username"
- label: "Instagram"
icon: "fab fa-fw fa-instagram"
url: "https://instagram.com/username"
これにより、Speaker Deck や Slideshare といったこれまでサポートされていなかったサービスのリンクも (Font Awesome で目的のアイコンを探す必要はありますが) 自由に追加できるようになりました。
フッターリンクの記述
著者情報のリンクと同様に、フッターのリンクも _config.yml
で自由に制御できるようになりました。記述方法もほぼ同じで、以下のようになります。
footer:
links:
- label: "Twitter"
icon: "fab fa-fw fa-twitter-square"
url: "https://twitter.com/username"
- label: "Facebook"
icon: "fab fa-fw fa-facebook-square"
url: "https://facebook.com/username"
- label: "GitHub"
icon: "fab fa-fw fa-github"
url: "https://github.com/username"
base_path の削除
以前存在していた base_path
のヘルパーが 削除された ことによって、{% include base_path %}
の Liquid タグが含まれたファイルが存在すると以下の類のエラーが出力されるようになりました。
Jekyll Feed: Generating feed for posts
Liquid Exception: Could not locate the included file 'base_path' in any of ["/work/_includes", "/usr/local/bundle/gems/minimal-mistakes-jekyll-4.16.4/_includes"]. Ensure it exists in one of those directories and, if it is a symlink, does not point outside your site source. in index.html
Error: Could not locate the included file 'base_path' in any of ["/work/_includes", "/usr/local/bundle/gems/minimal-mistakes-jekyll-4.16.4/_includes"]. Ensure it exists in one of those directories and, if it is a symlink, does not point outside your site source.
Error: Run jekyll build --trace for more information.
そもそも、このブログではもはや base_path
は使っていなかったので、削除して対処しました。
Docker 化のハマりどころ
以降は Jekyll + Minimal Mistakes の環境を Docker 化するにあたって、ハマったポイントになります。
ロケールの設定
前述した Dockerfile
には、以下のようにロケール設定の記述がありました。
# (ロケール設定部分を抜粋)
RUN set -ex \
&& apt-get update \
&& apt-get install -y \
locales \
locales-all \
&& locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
仮にこのロケールを 設定することなく ビルドした Docker イメージを使って jekyll build
もしくは jekyll serve
した場合、以下のように scss ファイルのコンパイルで Invalid US-ASCII character
が発生してしまいます。
make jekyll-serve
# (省略)
Configuration file: _config.yml
Source: /work
Destination: /work/_site
Incremental build: enabled
Generating...
Jekyll Feed: Generating feed for posts
Conversion error: Jekyll::Converters::Scss encountered an error while converting 'assets/css/main.scss':
Invalid US-ASCII character "\xE2" on line 54
jekyll 3.8.5 | Error: Invalid US-ASCII character "\xE2" on line 54
make: *** [jekyll-serve] Error 1
コンテナ外からの WEBrick サーバへのアクセス
Docker コンテナ上に jekyll serve
で立ち上げた HTTP サーバ (WEBrick) に コンテナ外 からアクセスする場合、-h, --host
オプションなどで 0.0.0.0
にバインドする必要があります。これを怠ると、コンテナ内からは curl http://localhost:4000/
でレスポンスが得られるけどコンテナ外からだと疎通できない… みたいな状況に陥ります。
まとめ
Gem 化によって Minimal Mistakes のテーマを使った Jekyll 環境の構築は随分と楽になりましたが、さらに Docker 化することで、環境を新しい PC に移行することも楽にできるようになりました。
なお Docker 化した Minimal Mistakes + Jekyll の環境は komiya-atsushi/dockerized-minimal-mistakes-jekyll-example にてそのサンプルを公開しています。