DockerでHugo環境構築

2019-09-15
2019-09-15

はじめに

どうも、おい丸です。

今回は普段このサイトで使っている Hugo に関する記事です。

最近、以前から使っていた Macbook とは別に機械学習用のノート PC を買いました。

新しいノート PC でも同じようにブログの更新をしたいと思い、どうせなら Docker で環境作ろうということでやってみました。

環境

今回作業を行った環境は以下になります。

NAME="Ubuntu"
VERSION="18.04.3 LTS (Bionic Beaver)"
Docker version 19.03.2
docker-compose version 1.24.1

また、Hugo の作業フォルダは作成済みとします。

※ docker のインストール方法には触れません

やりたいこと

やりたいことは、docker(docker-compose)さえあれば、どのデバイスからでも Hugo でブログ更新ができるようにすることです。

データは github にあがっているので、clone すればどこでも使えます。 なので今回の環境でコンテナに求められるのは、以下の 2 つ

  • 新規記事作成コマンドが使える
  • localhost:1313 でプレビューできる

Docker を使った Hugo 環境の作成方法

まずは Docker Hub で Hugo の image がないか探しました。

やはり、Docker Hub にはたくさんの Hugo 用 image がありました。

今回は以下の Docker image を使います。

選んだ理由としては他のサイトで ↑ が使われていてちゃんと動作しているようだったからです。
また、image が非常に軽量だったというのもあります。

それでは、環境を作っていきます。

まずは、Docker 用のフォルダを作成します。
作成場所はどこでもよいと思いますが、私は Hugo の作業フォルダと同じ階層にしました。

.
├── Docker
└── hugo_folda # Hugo作業フォルダ

今回はより簡単に使えるように docker-compose を使用します。

Dockerフォルダ配下にdocker-compose.ymlを作成します。
内容は以下になります。

version: "3"
services:
  work:
    image: klakegg/hugo:0.58.2-alpine
    volumes:
     - ../hugo_folda:/src
    ports:
      - "1313:1313"
    command: shell

私の場合は、コンテナ内に入って Hugo コマンドを使いたかったので上記のような内容にしました。
私と違う場所に Docker フォルダをおいた方は、マウントするフォルダ場所などを適宜変えてください。

作成者の readme を読めばわかるのですが、build だけ serve だけのような使い分けも簡単にできるようになっています。

おそらく、Docker for Mac の人だと上記内容でうまくいくはずです。

しかし、私のような ubuntu ユーザーの場合はコンテナ内でファイルを作成すると、ホスト側のユーザからは権限がないといわれ編集できなくなってしまう可能性があります。

調べると Linux の人はホストとコンテナの owner が別になってしまうらしいです。
こちらと同じ現象です。

参考:docker で volume をマウントしたときのファイルの owner 問題

この記事を参考にしつつ以下のように書き換えます。

version: '3'
services:
  work:
    user: '${UID}:${GID}'
    image: klakegg/hugo:0.58.2-alpine
    volumes:
      - /etc/group:/etc/group:ro
      - /etc/passwd:/etc/passwd:ro
      - ../hugo_folda:/src
    ports:
      - '1313:1313'
    command: shell

次に、user: "${UID}:${GID}"の環境変数を定義するのに.envファイルをDockerフォルダ配下に作成します。
内容は以下の通り簡単です。

UID=<uidの>
GID=<gidの>

ちなみに uid と gid の値はidコマンドで調べられます。

.envファイルを書かなくても、ホスト側で環境変数として GID と UID を定義してもオッケーです。

これで準備はできました。

Dockerフォルダに移動し、以下のコマンドで実行します。

docker-compose run --service-ports work

今回はコンテナが一つなのでrunを使いました。

実行すると以下のようになり、コンテナが起動して中で作業ができます。

result

フォルダがマウントしてあるので、editer を使ってファイルの編集をしたり、また 1313 に port フォワードもしているので、いつもどおり Hugo のプレビュー機能も使えます。

ハマったところ

今回の環境でビルドしたサイトのレイアウトが変わってしまっていたことです。
原因は、おそらく普段使っている Hugo のバージョンが 0.54 で今回の環境では 0.58 を使用したからだと思います。

具体的な原因箇所は.Data.Pagesの部分です。
これでページをリストで取得していたのが、代わりに一個上の階層の一覧(contentsとかposts)が呼び出されるようになってしまっていました。

これは.Data.Pagesの部分を.Site.RegularPagesに修正すること解決できました。
(参考:Site Variables

あとは、上述したファイルのアクセス権問題です。

環境は docker の image を pull するだけだったので、簡単だったのですが、アクセス権問題がなかなか解決できず苦労しました。

最後は、port フォワードでdocker-compose run <service名>だとdocker-compose.ymlに書いた port フォワードが反映されなかったことです。
まあこれに関しては、公式に書いてあったのですぐ解決できました。

まとめ

Docker 便利ですね。
もっと早くやっておけばよかったです。

デプロイの自動化や環境構築もコード化されて、ようやくブログ更新環境が完成に近づいてきた気がします。