Post

[自分向け] JekyllをDockerでビルドするためのコンテナを作った

Jekyllコンテナを作った。

Docker Hubに存在する公式のJekyllのコンテナイメージはなぜかWebrickが入っていないと怒られ、ビルドができなく使い物にならなかったので、自分用に雑にビルドするためのコンテナを作成しました。

久々にDockerfileを書いたため、いい感じのリハビリにもなりました。

jekyll servejekyll buildもその他のコマンドもだいたい使うことができるはずです。

モノ

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
FROM ruby:3.1.2-bullseye

# パッケージ関連
RUN echo "リポジトリをrikenに変更します。" \
&&  echo "deb http://ftp.riken.jp/pub/Linux/debian/debian bullseye main contrib non-free" > /etc/apt/sources.list \
&&  echo "deb http://security.debian.org/debian-security bullseye-security main" >> /etc/apt/sources.list \
&&  apt update \
&&  apt upgrade -y \
&&  apt install -y \
      build-essential \
      git \
      sudo \
&&  echo "update完了しました。"

# 実行ユーザーを作成
ENV USER_NAME=jekyll
RUN echo "実行ユーザーを作成します。" \
&&  echo "${USER_NAME} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${USER_NAME} \
&&  chmod u+s /usr/sbin/useradd \
&&  chmod u+s /usr/sbin/groupadd

RUN  gem update \
&&  gem install jekyll bundler

ADD entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh \
&&  mkdir /usr/src/app -p \
&&  mkdir /usr/local/app -p
#WORKDIR /usr/src/app

ENTRYPOINT ["/bin/bash", "/usr/local/bin/entrypoint.sh"]
EXPOSE 4000

entrypoint.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/bin/bash
USER_ID=$(id -u)
GROUP_ID=$(id -g)

# 初期化
SRC_DIR=/usr/src/app
DEST_DIR=/usr/local/app

# グループを作成する
if [ x"$GROUP_ID" != x"0" ]; then
    groupadd -g $GROUP_ID $USER_NAME
fi

# ユーザを作成する
if [ x"$USER_ID" != x"0" ]; then
    useradd -d /home/$USER_NAME -m -s /bin/bash -u $USER_ID -g $GROUP_ID $USER_NAME
fi

# パーミッションを元に戻す
sudo chmod u-s /usr/sbin/useradd
sudo chmod u-s /usr/sbin/groupadd

# ディレクトリ作成
mkdir -p $SRC_DIR
mkdir -p $DEST_DIR
# パーミッション変更
sudo chown $USER_NAME:$USER_NAME $SRC_DIR
sudo chown $USER_NAME:$USER_NAME $DEST_DIR

exec $@

# 初期化
SRC_DIR=/usr/src/app
DEST_DIR=/usr/local/app

# ディレクトリ作成
mkdir -p $SRC_DIR
mkdir -p $DEST_DIR

# 設定値表示
echo "========================================"
echo "Source Dir      : ${SRC_DIR}"
echo "Target Dir      : ${DEST_DIR}"
echo "Jekyll Mode     : ${JEKYLL_MODE}"
echo "jekyll ARGS     : ${JEKYLL_ARGS}"
echo "jekyll NEW BLANK: ${JEKYLL_NEW_BLANK}"
echo "========================================"

cd $SRC_DIR

# $SRC_DIRが空ならば初期テンプレート作成
if [ -z "$(ls $SRC_DIR)" ]; then
  ${JEKYLL_NEW_BLANK:=false} #JEKYLL_NEW_BLANKが未定義の場合、falseを代入。
  if   [ $JEKYLL_NEW_BLANK = false ]; then
    echo "jekyll newを実行しました"
    jekyll new $SRC_DIR
  elif [ $JEKYLL_NEW_BLANK = true ]; then
    echo "jekyll new --blankを実行しました"
    jekyll new $SRC_DIR --blank
  else
    echo "JEKYLL_NEW_BLANKにBool以外の値が代入されています。"
    exit 1
  fi
fi

# Gemfileにwebrickがない場合追加
echo "GemfileにWebrickが記述されていない場合、追加します。"
grep -q "webrick" "${SRC_DIR}/Gemfile"
if [ $? -eq 0 ]; then
  echo "webrickはすでに入っています。"
elif [ $? -eq 1 ]; then
  echo $PWD
  echo "webrickを追加しました。"
  bundle add webrick
else
  echo "エラーが発生しました。 Exit Code: ${?}"
  exit 1
fi

# bundle
echo "Bundle installをします"
/usr/local/bundle/bin/bundle install

echo "========================================"

# Jekyll 起動
if   [ ${JEKYLL_MODE} = "serve"     ]; then
  /usr/local/bundle/bin/bundle exec jekyll serve     -s ${SRC_DIR} ${JEKYLL_ARGS} -d ${DEST_DIR} --host=0.0.0.0 --watch
elif [ ${JEKYLL_MODE} = "build"     ]; then
  /usr/local/bundle/bin/bundle exec jekyll build     -s ${SRC_DIR} ${JEKYLL_ARGS} -d ${DEST_DIR}
elif [ ${JEKYLL_MODE} = "doctor"    ]; then
  /usr/local/bundle/bin/bundle exec jekyll doctor    -s ${SRC_DIR} ${JEKYLL_ARGS} -d ${DEST_DIR}
elif [ ${JEKYLL_MODE} = "clean"     ]; then
  /usr/local/bundle/bin/bundle exec jekyll clean     -s ${SRC_DIR} ${JEKYLL_ARGS} -d ${DEST_DIR}
elif [ ${JEKYLL_MODE} = "new-theme" ]; then
  /usr/local/bundle/bin/bundle exec jekyll new-theme -s ${SRC_DIR} ${JEKYLL_ARGS} -d ${DEST_DIR}
else
  # それ以外はエラーを返す
  echo "モードが不適切です。使用可能なモードは(serve|build|doctor|clean|new-theme)です。"
  echo "newは/usr/src/appが空の場合、自動的に実行されます。"
  exit 1
fi

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: "3"
services:
  jekyll:
    build: ./build
    tty: true
    environment:
      TZ: Asia/Tokyo
      JEKYLL_MODE: "serve"
      JEKYLL_ARGS: ""
      JEKYLL_NEW_BLANK: false
    volumes:
      - ./app:/usr/src/app
    user: "1000:1000"
    ports:
      - 4000:4000

Jekyllを起動する処理など、気に入っていない部分が多々ありますが、自分用のコンテナとして一応動いているので、良しとします。

Dockerfileentrypoint.shをbuildディレクトリに入れ、docker-compose.ymlで適当に設定をし、

1
$ docker-compose build; docker-compose up -d

でもしてやると4000ポートで起動してくれます。

コンテナを起動する際に

  • JEKYLL_MODE
  • JEKYLL_ARGS
  • JEKYLL_NEW_BLANK

という環境変数を指定することができます。

JEKYLL_MODE

jekyll servejekyll buildなどのモードを入れる場所です。

(serve|build|doctor|clean|new-theme)が入力可能です。

jekyll newに関しては、ソースディレクトリが空の場合、事前に実行されます。

JEKYLL_ARGS

jekyllを起動する際のオプションです。

-s-dなどのオプションはすでに指定しています。その他のオプションを使用してください。`

なお、serveに関しては--host=0.0.0.0及び--watchオプションはすでに指定されます。

JEKYLL_NEW_BLANK

jekyllのソースディレクトリが空の場合、jekyll newが自動的に実行されますが、その際に--blankオプションを有効にするか否かのオプションです。

その他

もう少し改良したい点があるので、気が済んだらGitHubにでも上げておきます。

このサイトを置くホスティングサービスどうしようかなぁ。。。

レンタルサーバーとかはこの性能でこの値段かぁ・・・みたいなのが多くてアレ。(自宅サーバーと比較するな)(性能気にしたくなくてSSGにしたんだろ)

無償のならばCloudFlare Pagesがいい感じに良さそうな気はする。

問題は、リポジトリ置き場かなぁ・・・。

今みたいに、文章をメインにしたブログならば、サイズは肥大化しなくて済むのですが、画像を多く使い始めるような使い方をすると、GitHubのリポジトリサイズ10GB制限に引っ掛かりそうです。

画像ホスティングサービスにアップロードするという手段もありますが、別個にするとそれぞれ管理せねばならず、めんどくさいのと、その画像ホスティングサービスがサービス終了した場合、泣きを見ることになるので、あんまり乗り気ではありません。

コンテンツは CC BY-NC-SA 4.0 の下で利用できます。