Hugo + Travis CI + Github pagesで独自ドメイン+HTTPSなWebページを公開する
きっかけ
自宅サーバをリプレースするにあたり,必要ないものはとことん外部サービスに突っ込んでいくことを検討しました.
所謂""脱オンプレ""を目指すにあたり,自身のWebページには下記の条件を満たすことを目標としました.
- 独自ドメインが使えること
- HTTPS対応であること
- Githubへのpushをトリガーに自動で公開が出来ること
- 静的サイトジェネレータを使用し,Markdownを書くだけで済むこと
- できるだけ安価に済ませること
これらを満たす方法をいくつか検討しましたが,最終的にGithub pagesが独自ドメインのHTTPSをサポートした*1ことにより,収束しました.
Hugoとは
Go言語製の静的サイトジェネレータです.
バイナリ一つで動くため依存が少なく,異なるプラットフォーム間でも手軽に導入でき,扱いやすいためです.
とにかくコンパイルが早く,あっという間に記事が生成されます.主にブログとかを書くのがメインなんですが,今回はシングルページの個人プロフィール的なサイトを運営します.
Travis CIを選んだ理由
いつものごとく,慣れているから,です.
今回のように複雑なテスト,特殊なビルド環境を必要としない場合,簡潔に書けてgithub pagesへのデプロイにも対応している点は魅力かなと思います.
Github Pagesとは
Githubでホストしている静的ファイルをWebサイトとして公開できる機能です.
基本的には {user名}.github.io/{リポジトリ名}で公開されますが,リポジトリ名を{user名}.github.ioとすると,{user名}.github.ioでページが公開されるようになります.
ただしこの場合masterブランチからしか公開できない設定になってしまい,CIによるビルド・デプロイと相性が悪い*2ので,別のリポジトリ名を設定します.今回は適当にwebとしました.
ページを作る
テーマの選択
からテーマを探します.どれもよく出来ていて,だいたいリポジトリの中にサンプルのconfig.tomlや.mdファイルが入っているので,それを参考に書いていきます.
hugoのインストール
公式の手順が公開されています.Macではbrewを,Windowsではchocolateyを推奨しているようです.Linuxではgo getしてビルドで使えるようになります.
また,Github Releasesで.debパッケージなども公開されているので,導入は難しくないと思います.
今回の環境は下記の通りですが,どのプラットフォームでもそれほどやることは変わらないだろうと思います.
サイトの作成
まずはhugoのプロジェクトの雛形を作成します.
$ hugo new site web Congratulations! Your new Hugo site is created in /path/to/web Just a few more steps and you're ready to go: 1. Download a theme into the same-named folder. Choose a theme from https://themes.gohugo.io/, or create your own with the "hugo new theme <THEMENAME>" command. 2. Perhaps you want to add some content. You can add single files with "hugo new <SECTIONNAME>/<FILENAME>.<FORMAT>". 3. Start the built-in live server via "hugo server". Visit https://gohugo.io/ for quickstart guide and full documentation.
以下の様な感じのディレクトリが作成されます.
$ cd web $ tree . ├── archetypes │ └── default.md ├── config.toml ├── content ├── data ├── layouts ├── static └── themes
config.tomlで主な設定を変更し,content以下に.mdなどを作っていく感じになります.
テーマの追加
今回はこちらを採用
gitで管理するのでまずはプロジェクト直下で初期化します.
$ pwd /path/to/web $ git init
次に,テーマを追加するのですが,様々な手法があります.zipをダウンロードしてきて展開してもいいのですが,せっかくgitで管理されているテーマなので,submoduleとして追加します.
$ git submodule add https://github.com/sethmacleod/dimension themes/dimension
themesディレクトリ以下に追加するのがミソです.
$ tree -L 3
.
├── archetypes
│ └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes
└── dimension
├── LICENSE.md
├── README.md
├── archetypes
├── exampleSite
├── images
├── layouts
├── static
└── theme.toml
サンプルをコピーして編集
themes/dimension/exampleSite以下に,サンプルページのconfigやmdが入っています.これを元に編集するのが楽かなと思います.
$ cp -r themes/dimension/exampleSite/ ./
後はconfig.tomlを編集します.編集上の注意点は各テーマによって異なるのでここでは扱いません.リポジトリのREADME等をよく読んでください.
次にcontentディレクトリ以下のファイルを編集していきます.ここも各テーマにしたがってください.
プレビューする
文法が間違っていない限り,hugoでビルド・プレビューできます.
$ pwd
/path/to/web
$ hugo server
| EN | DE
+------------------+----+----+
Pages | 2 | 2
Paginator pages | 0 | 0
Non-page files | 0 | 0
Static files | 41 | 41
Processed images | 0 | 0
Aliases | 1 | 1
Sitemaps | 2 | 1
Cleaned | 0 | 0
Total in 41 ms
Watching for changes in /path/to/{user名}.github.io/{content,data,layouts,static,themes}
Watching for config changes in /path/to/{user名}.github.io/config.toml
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop
localhost:1313にアクセスするとページが表示されるはずです.

ビルドしてみる
プレビュー時にはビルドが行われないため,一度ビルドしてどうなるかを確かめておきましょう.
$ hugo
| EN | DE
+------------------+----+----+
Pages | 2 | 2
Paginator pages | 0 | 0
Non-page files | 0 | 0
Static files | 41 | 41
Processed images | 0 | 0
Aliases | 1 | 1
Sitemaps | 2 | 1
Cleaned | 0 | 0
Total in 45 ms
publicディレクトリ以下にビルド後のファイルが格納されます.
$ ll public/ total 32 drwxr-xr-x 7 pudding staff 224B Jun 7 14:29 css drwxr-xr-x 5 pudding staff 160B Jun 7 14:45 de drwxr-xr-x 4 pudding staff 128B Jun 7 14:45 en drwxr-xr-x 8 pudding staff 256B Jun 7 14:29 fonts drwxr-xr-x 7 pudding staff 224B Jun 7 14:32 images -rw-r--r-- 1 pudding staff 5.6K Jun 7 14:45 index.html drwxr-xr-x 6 pudding staff 192B Jun 7 14:29 js -rw-r--r-- 1 pudding staff 64B Jun 7 14:45 robots.txt drwxr-xr-x 9 pudding staff 288B Jun 7 14:29 sass -rw-r--r-- 1 pudding staff 351B Jun 7 14:45 sitemap.xml
良い感じですね.
Github pagesへ自動デプロイする
リポジトリを作成してpush
特に解説しません.普通にwebというリポジトリを作成します.
$ git remote add origin https://github.com/{user名}/web
ビルド後のファイルはpushしたくないのでgitignoreに追加しておきます.
$ echo public/* >> .gitignore
後はaddしてcommitしてpush
$ git add . $ git commit -m 'init' $ git push -u origin master
Travis CIへ登録
別サイト様を参考に
Githubからトークンを取得
settingsを開き,Developer settings > Personal access tokens > Generate new token から新しいトークンを取得します.

取得したTokenをTravis CIの該当リポジトリの環境変数に追加します.

ついでに設定もしておきます.無駄にビルドが走っても仕方ないのでPull Request時の自動ビルドは止めておきます.
.travis.ymlを書く
よく内部でgit pushを叩いている例を見かけますが,Travis CIにはGithub Pagesへデプロイするための設定項目が存在します.
GitHub Pages Deployment - Travis CI
上記ページを参考に設定します.今回は別にgoを必要としませんが,一応goの環境を選択します.
language: go dist: trusty # これでdockerコンテナとして立ち上がるので起動が速い sudo: false env: # 良い方法が思い浮かばないのでバージョンを固定 - HUGO_VERSION=0.41 # このセクションを挟まないと勝手にgo getを走らせようとしてこける install: true # .debパッケージをダウンロードしてインストール before_script: - wget https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.deb - sudo dpkg -i hugo_${HUGO_VERSION}_Linux-64bit.deb # ビルドを実行 script: - hugo -v # デプロイの設定 deploy: # github pages用のプロバイダを設定 provider: pages # 公開するファイルがあるディレクトリを指定 local-dir: public # scriptセクションで実行したビルド結果をそのまま残す skip-cleanup: true # githubから取得したpersonal access token github-token: $GITHUB_TOKEN # force pushせずにcommitを重ねる keep-history: true # masterブランチへのpush時のみに限る on: branch: master
branch切ってaddしてcommitしてpush
$ git checkout -b feature/auto-deployment $ git add .travis.yml $ git commit -m 'add .travis.yml' $ git push origin feature/auto-deployment
ビルド結果を確認してグリーンならOKです.(何回か試していたのでcommitコメントが違うとか何回ビルドしているんだっていう指摘は無しで)

gh-pagesへpushされることを確認
masterブランチへのPull requestを作成してマージします.
うまく設定できれいればmasterブランチでCIが動き,デプロイが実行されます.

こんな感じでmasterから完全に独立したgh-pagesブランチが作れられます(何度かpushしている例です).

公開されているか確認
https://{user名}.github.io/web/にアクセスして表示されればOK
表示が崩れる場合,cssやjsを正しく読み込めていない可能性があります.
config.tomlに設定を書きましょう.
baseurl = "http://{user名}.github.io/web/"
canonifyurls = true
独自ドメインのセットアップ
だいたいここに書いてます.
Using a custom domain with GitHub Pages - User Documentation
CNAMEレコードの設定
適当にドメイン名をexample.comとしておきます.今回はwww.example.comでWebページを公開します.
DNSの設定をします.今回は例としてお名前ドットコムを上げますが,どこでも基本は変わらないでしょう.
| ホスト名 | Type | TTL | Value |
|---|---|---|---|
www.example.com |
CNAME | 3600 | {user名}.github.io |
もしexample.comでもページを表示したい場合,Aレコードを設定するのでは無く,URL転送機能などを使ってexample.comへのアクセスをwww.example.comへ転送しましょう.独自ドメインでhttpsを利用する場合,githubは自動でexample.comとwww.example.comでリダイレクトしてくれません*3.
Github Pagesのカスタムドメインを設定
$ git checkout master $ git pull $ git checkout -b feature/custom_domain
Webから叩いても良いですが,Travis CIのGithub pages deployにはカスタムドメインの設定項目がありますのでそっちからやりましょう..travis.ymlを編集します.
# デプロイの設定 deploy: # 独自ドメインを設定 fqdn: www.example.com provider: pages local-dir: public skip-cleanup: true github-token: $GITHUB_TOKEN keep-history: true on: branch: master
config.tomlも設定します.
baseurl = "https://www.example.com/"
pushしてPull requestを発行します.
$ git push origin feature/custom_domain
マージして変更が反映されるのを確認します.
カスタムドメインでのアクセスを確認
上手くいっていれば数分でhttps://www.example.com/にアクセスすることでページが見れるようになるはずですが,うまくいかないこともあります.
Enforces HTTPSの設定がいつまでもグレーアウトし,証明書の発行がされていない旨の警告が出る場合は一度ドメインを削除して再設定する必要があります*4
よくヘルプを読みましょう…

まとめ
自分でWebサーバーをホストすることなくWebサイトを公開する手法はこれまでもいくつかありましたが,HTTPS+独自ドメインが使えて,最小構成ではgithubに閉じて運用できることはメリットかなと思います.
みんな良い感じにページを公開していきましょう!
*2:ビルド後の成果物をmasterブランチへpushするため,手元の環境で毎回pullしないといけなかったり,masterブランチで無駄にdiffが発生してしまうため
*3:Setting up an apex domain and www subdomain - User Documentation
*4:Adding or removing a custom domain for your GitHub Pages site - User Documentation