github の hugo を clone して docker build すれば docker の環境は出来るので、書くまでもないと言えば書くまでもない。
2022 April に再構築しようと思って自分の記事を見てる。
TL;DR
正式版と Draft 版の二つの Hugo サーバを立ち上げ、Draft でうまくいったら git をつかって、正式版から pull して反映するという環境を作りたい。
そのために hugo + git の docker 環境 + ホスト側に同じバージョンの hugo が必要になった。go の環境はあまり関係なかった、、、
まずは出来た Docker のイメージを使う
sinby/hugo-git:0.97.3-extended で公開しているので
% sudo docker run --rm -v =0/site:/site 0.97.3-extended new site .
こんな感じでまずは site を構築する。=0 は tcsh の機能なので、bash 使っている人とかは $(pwd) とかに置き換えることになるでしょう。(2022 に入って bash 派に転校しました)
ところで、いったいこれはなにをしているのか?
/site を構築したのだ
docker 内の /site に hugo の source が設定されている(というかカレントディレクトリが /site になるみたい)。参考までに書くと hugo でこのディレクトリを変えるには --source string で変更する。
/site は docker の中にあるのでアクセスできないと一切何もできない。なので、-v で docker のホストの site ディレクトリを /site にするように設定している。
sinby/hugo-git:0.97.3-extended は 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.97.3-extended 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 とするみたい。なんか直感的には逆なんだけど URL にかいてある port を無視するという意味みたいね)
> sudo chown -R <user>:<group> site
> mv site draft
> sudo docker run --rm -v =0/draft:/site -p 31313:1313 0.97.3-extended 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.18.1 linux/amd64
[2022] ついでに 1.15.8 から 1.18.1 にバージョンアップ!!
$ ls -l /usr/local
...
lrwxrwxrwx 1 root root 9 4月 22 13:53 go -> go-1.18.1/
drwxr-xr-x 10 root root 4096 2月 5 2021 go-1.15.8/
drwxr-xr-x 10 root root 4096 4月 13 00:42 go-1.18.1/
...
参考までに書くとこの /usr/local/go の環境(SDK?) が GOROOT になるようです。(ここでは必要がなかったので特に環境変数は設定していません)
mage のインストール
hugo の build に mage が必要です。そこで mage を get します。 install になったようです。ここではクリーンに作りたいので GOPATH を ~/Hugo/go に設定しておきます。
> setenv GOPATH ~/Hugo/go
> go get github.com/magefile/mage
[2022 bash版]
$ go install github.com/magefile/mage@latest
go: downloading github.com/magefile/mage v1.13.0
これで ~/Hugo/go/bin に mage というコマンドが追加されました。path に追加しておきましょう。
hugo の build(2021古い情報)
get は deprecated なので installを使います(後述)ここでは歴史的経緯を残す意味で削りません。
ソースを持ってくるのに 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
hugo の build どうする?[2022版]
get は deprecated になったのでどうすればいいの?
https://github.com/gohugoio/hugo
をみると
mkdir $HOME/src
cd $HOME/src
git clone https://github.com/gohugoio/hugo.git
cd hugo
go install
らしいので、おもむろに release-0.97.3 で install
$ cd hugo
$ git checkout -b release-0.97.3
$ go install
go: downloading github.com/alecthomas/chroma v0.10.0
go: downloading github.com/bep/overlayfs v0.6.0
go: downloading github.com/fsnotify/fsnotify v1.5.1
go: downloading github.com/spf13/afero v1.8.2
go: downloading github.com/spf13/cobra v1.4.0
go: downloading golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
go: downloading golang.org/x/sys v0.0.0-20220209214540-3681064d5158
...途中略
go: downloading github.com/go-openapi/swag v0.19.5
go: downloading github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e
うまくいけば hugo が ~/Hugo/go/bin にインストールされます。あれ?なぜか v0.98.0-DEV。なぞ。
$~/Hugo/go/bin/hugo version
hugo v0.98.0-DEV-41cc4e4ba3bd849cee7dcb691504ebebbfce680f linux/amd64 BuildDate=2022-04-18T18:01:38Z
sunra:hugo$ git branch
master
* release-0.97.3
v0.80.0
ホスト側でコンテンツを登録して編集
できるかな~
> 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 を再立ち上げとかしましたが、、、なんとか目的通りのことが出来ました。
一通り確認
- 1313 で正式版立ち上げ
- 31313 でdraft 版立ち上げ
- draft の content を編集 => draft 版のサーバで変更がリアルタイムに確認できる。draft の行が入ったものも見ることができる。
- content の編集と draft の行を削る。
- git commit する。
- 1313 に git pull を exec => 正式版のサーバで変更がリアルタイムに確認できる。draft の行が入ったものは見ることができない。
sudo docker exec -it <containerID> git pull
最後の手順で sudo を必要とするけど、まぁいいんじゃないって感じ。
おまけ。hugo-fresh を使う [2022]
Bulma という CSS がよさそうです。bootstrap よりわかりやすくシンプルかな。hugo-fresh という theme で使われています。ananke はちょっと(私には)大げさだった。
おまけ。reveal も使う[2022]
スライドを使うなら reveal 。超便利。フォントの大きさも変えられる。hugo-fresh と共存できます。
theme = ["hugo-fresh-asagao", "reveal-hugo"]
おまけ。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 して独自スタイルに成長させる(各自がテーマを持つ)という風になる気がしますよ。
感想
よくできているような、難しいような。hugo-fresh を読んででだいぶ理解が進みました。Hugo で range はできるけど foreach 的なことはできないみたいなので、結局、最後は lisp に戻るかも。デザイン上の良し悪しは結局ツールじゃなくて HTML5 CSS JS に集約されるから。それをうまく組み合わせることを助けてくれるツールがいいよね。
いまのところ WordPress にしても Hugo にしても助けてくれるというよりはその Theme を使え的なところがある。