Hugo を導入する過程で go の環境とか作る


github の hugo を clone して docker build すれば docker の環境は出来るので、書くまでもないと言えば書くまでもない。

TL;DR

正式版と Draft 版の二つの Hugo サーバを立ち上げ、Draft でうまくいったら git をつかって、正式版から pull して反映するという環境を作りたい。

そのために hugo + git の docker 環境 + ホスト側に同じバージョンの hugo が必要になった。go の環境はあまり関係なかった、、、

まずは出来た Docker のイメージを使う

sinby/hugo-git:0.80.0 で公開しているので

% sudo docker run --rm -v =0/site:/site sinby/hugo-git:0.80.0 new site .

こんな感じでまずは site を構築する。=0 は tcsh の機能なので、bash 使っている人とかは $(pwd) とかに置き換えることになるでしょう。

ところで、いったいこれはなにをしているのか?

/site を構築したのだ

docker 内の /site に hugo の source が設定されている(というかカレントディレクトリが /site になるみたい)。参考までに書くと hugo でこのディレクトリを変えるには --source string で変更する。

/site は docker の中にあるのでアクセスできないと一切何もできない。なので、-v で docker のホストの site ディレクトリを /site にするように設定している。

sinby/hugo-git:0.80.0 は docker 内の hugo を起動するので引数に new site . を指定する。これは docker 内に login して

( cd /site ; hugo new site . )

としたのと同じだ。run で --rm 指定しているのでコマンドの実行が終了すると(つまり hugo コマンドが終了すると)docker 自身もコンテナとして終了し、そしてイメージを消去する。

これ(--rm ね)をつけないと山のように終了したイメージの残骸が docker が管理するディスク上のどっかに蓄積していくことになる。

hugo 実行しただけじゃん

ってことはこれ hugo 実行しただけじゃん。例えば version 。

% sudo docker run --rm -v =0/site:/site sinby/hugo-git:0.80.0 version

これ docker 起動して hugo version 実行して docker 終了して、イメージを消すというかなり簡単なことを大げさに実行する。だとしたら、手元に hugo 0.80.0 があれば

% hugo new site site

とと下のほぼ等価。まぁ最新の hugo をインストールするのにちょっとこつがいるんだけどね(後述)。

つづけて hugo をサーバーとして起動

% sudo docker run --rm -v =0/site:/site -p 1313:1313 sinby/hugo-git:0.80.0 server -D --watch  --bind 0.0.0.0

-D と --watch で draft も表示させつつつデバッグ用として起動。これで Docker のホストからは 1313 で hugo をみることができる。が、まだ何も設定してないので、エラー表示されるでしょう。

docker の中に入って設定をする

いや~これおかしいけどね。docker ps であらかじめ調べておいた Container ID で exec で中に入る。login みたいなもんだね。

手順は https://gohugo.io/getting-started/quick-start/ とほぼ同じ

sudo docker exec -it <ContainerID> /bin/ash
/site #
/site # git init
/site # git clone https://github.com/budparr/gohugo-theme-ananke.git themes/ananke
/site # echo 'theme = "ananke"' >> config.toml

ついでにちょっとコンテンツも追加

/site # hugo new posts/0212-0.md
/site/content/posts/0212-0.md created

折角 /site がホストに出ているのに、docker の中に入って作業するのおかしいけど、とりあえず、ここまででいろいろできるということで。あと、config.toml の中の baseURL も変更しておきましょう。

baseURL = "http://192.168.0.XXX:1313/"

あれ?うまくいかないな、立ち上げの時に -b で指定するとうまくいく。う~ん。まぁいいや。これで回避。

% sudo docker run --rm -v =0/site:/site -p 1313:1313 sinby/hugo-git:0.80.0 server -D --watch  --bind 0.0.0.0 -b 192.168.0.XXX:1313

ブラウザーで動作確認出来たらここで最初のミッション完了。

ドラフトなサーバとして仕上げる

折角、Docker のホストから /site が見えているのに、わざわざ exec で docker 内に入った理由は site のすべてのファイルのオーナが root だからです。さっきつくった posts/0212-0.md も vim で編集するのに sudo が必要になったりして、大変回りくどくなります。

そこで、ホスト側で編集できるように chown してしまいます( と には適切な名称を入れてください)。そして draft なサーバとして再度立ち上げます。そのためディレクトリ名を site から draft に変更します。ポートも 31313 にします(--appendPort=false とするみたい。なんか直感的には逆なんだけど)

> sudo chown -R <user>:<group> site
> mv site draft
> sudo docker run --rm -v =0/draft:/site -p 31313:1313 sinby/hugo-git:0.80.0 server -D --bind 0.0.0.0 -b 192.168.0.XXX:31313 --appendPort=false
Start building sites …

ホスト側で編集

これでホスト側で編集できるはずです。お!できました。

ホストに同じバージョンの hugo をいれる

ここが難しかった。

実は、この方法は hugo の Dockefile をホストで実行しているだけです。

まずは最新の go を導入

apt とかで入れると古めの go が入るので、とりあえず apt でいれた golang も remove して、本家から tar.gz をとってきて /usr/local に解凍。/usr/local/go/bin を path についかしておきます。これで go コマンドが実行可能になりました。

> go version
go version go1.13.8 linux/amd64

参考までに書くとこの /usr/local/go の環境(SDK?) が GOROOT になるようです。(ここでは必要がなかったので特に環境変数は設定していません)

mage のインストール

hugo の build に mage が必要です。そこで mage を get します。ここではクリーンに作りたいので GOPATH を ~/Hugo/go に設定しておきます。

> setenv GOPATH ~/Hugo/go
> go get github.com/magefile/mage

これで ~/Hugo/go/bin に mage というコマンドが追加されました。path に追加しておきましょう。

hugo の build

ソースを持ってくるのに go get を使うと途中でいくつかエラーになります。なぜだかはわかりません。依存関係がおかしな具合になっているように見えます。

そこで、Docker ファイルにあるように clone してコピーします。そして mage でビルド・インストールします。

> cd ~/Hugo/go/src/github.com
> mkdir gohugoio
> cd gohugoio
> git clone https://github.com/gohugoio/hugo.git
> cd hugo
> mage hugo
> mage install

うまくいけば hugo が ~/Hugo/go/bin にインストールされます。

> ~/Hugo/go/bin/hugo version
Hugo Static Site Generator v0.80.0-792EF0F4 linux/amd64 BuildDate: 2021-02-12T12:35:21+0900

ホスト側でコンテンツを登録して編集

できるかな~

> cd draft
> hugo new posts/0212-1.md
> vim content/posts/0212-1.md

お~できた。

とりあえず draft で git commit しておきます。

> git add archetypes/ config.toml  content/
> git commit

ドラフトじゃないサーバを立ち上げる

sudo docker run --rm -v =0/site:/site sinby/hugo-git:0.80.0 new site .
sudo docker run --rm -v =0/site:/site -v =0/draft:/draft -p 1313:1313 sinby/hugo-git:0.80.0 server --bind 0.0.0.0 --baseURL=192.168.0.X

いいかげん docker-compose で便利にしよう

version: '3'

services:
    server:
        image: sinby/hugo-git:0.80.0
        command: server --bind 0.0.0.0 --baseURL=192.168.0.X
        volumes:
            - "./site:/site"
            - "./draft:/draft"
        ports:
            - "1313:1313"

draft から clone

なんかうまくいかなかったのでかなり無理矢理。

/site # git clone /draft
/site # mv draft/.git .git
/site # git remote -v
origin  /draft (fetch)
origin  /draft (push)
/site # git fetch
/site # git log

commit b1fc9f11d960c5ae604e88e89ce976747288a085 (HEAD -> master, origin/master,
origin/HEAD)
Author: RS
Date:   Fri Feb 12 08:57:02 2021 +0000

    submodule をやめた

commit 2270efcb1a56bf68f864322797ee011ba303557b
Author: RS
Date:   Fri Feb 12 08:36:48 2021 +0000

    コンテンツ増えた。
/site # git reset --hard
/site # ls -R content
content:
posts

content/posts:
0212-0.md  0212-1.md

/site # git clone /draft/themes/ananke/ themes/ananke
/site # ls themes/
ananke

reset --hard がかなり無理矢理感がありますが、まぁわかってやっているので良しとしましょう。ananke も clone しておきます。

なんか、とちゅうごちゃごちゃになって、docker を再立ち上げとかしましたが、、、なんとか目的通りのことが出来ました。

一通り確認

  1. 1313 で正式版立ち上げ
  2. 31313 でdraft 版立ち上げ
  3. draft の content を編集 => draft 版のサーバで変更がリアルタイムに確認できる。draft の行が入ったものも見ることができる。
  4. content の編集と draft の行を削る。
  5. git commit する。
  6. 1313 に git pull を exec => 正式版のサーバで変更がリアルタイムに確認できる。draft の行が入ったものは見ることができない。
sudo docker exec -it <containerID> git pull

最後の手順で sudo を必要とするけど、まぁいいんじゃないって感じ。

おまけ。ananke をちょっと使いやすく?する

たぶん thema は ananke を拝借しながら、今後は独自に発展すると思われるので意図的に clone にしました(submodule にしなかった。submodule にすると clone 先で本家を参照するから)。

ananke 以外の themes が必要な時は適宜 docker を立ち上げればいいでしょう。例えばスライド用に slide.example.com で、 themes をスライドから拝借、docs.example.com で themes は docsy にするとか。

i18n を追加して

ソースの一番上(/draft とか) でi18n を追加して ja.toml も追加(en.toml からコピー)。そして Recent を最近のに read more を続きはこちらに変更

> mkdir i18n
y> diff i18n/ja.toml  themes/ananke/i18n/en.toml
8c8
< other = "最近の {{.Title }}"
---
> other = "Recent {{.Title }}"
11c11
< other = "続きはこちら"
---
> other = "read more"

config.toml に DefaultContentLanguage を追加

DefaultContentLanguage = "ja"
```

メニューも追加

config.toml にメニューも追加

[[menu.main]]
identifier = "posts"
name = "posts"
url = "/posts/"

なんとなくですが、WordPress の themes とはちがい、自分でどっかから themes を clone してそれを変えていた方がよさそう。複数の themes からその機能が欲しいときは自分でコピペする。そうすると、どんどん最初の themes とは違うものになっていくでしょう。

ということは themes にとらわれる(こだわる)のではなく clone して独自スタイルに成長させる(各自がテーマを持つ)という風になる気がしますよ。