思い立って先日の3連休で本ブログ https://blog.mizukmb.net を IBM Bluemix から Docker コンテナに移行しました。 IBM Bluemix については Hugo + IBM Bluemix でブログを作りなおした を御覧ください。
モチベーション
以前からこのブログを PaaS から VPS に引っ越して、アクセスログを収集したりサーバの監視などをやってみたいと思っていました。しかしながら、いざやろうにも全くやる気が起きずだらだらと後に延ばし続ける日々を送っていました。 そんな時、シャワーを浴びていたらふと頭のなかで 『ブログを Docker で動かせば面白いのでは』 と謎のアイデアが浮かんだので、この3連休でゼルダの伝説を遊びながら構築した次第であります。
その結果、運用コストを無視した完全に興味だけで完成した構成となりました。
構成
雑な図です。
VPS は ConoHa の一番安いプランを借りました。月額600円くらい。 OS は CentOS 7.3
$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
サーバ調達 〜 Docker install まで
サーバは上述の通り、 ConoHa VPS を借りました。
Docker install までのサーバ構築は、手動でぱぱっとやっても良かったのですが、いい機会だったので MItamae でコード化しました。 この規模で Chef を使うのは流石に大げさだったので itamae or MItamae かなあと思ってました。今回はバイナリファイルで配布されていて、 itamae と互換性のある MItamae をつかうことにしました。 MItamae recipe で管理しているミドルウェアは以下になります。
- Git
- mackerel-agent
- Docker
- docker-compose
このくらいなら全部 recipe.rb みたいに 1 ファイルにまとめても問題ありません。ミニマルなファイル構成で実行できるのが MItamae のいいところですね。
以下、 recipe.rb の中身です。
package 'git'
mackerel_api_key = "******************************"
# ref: https://mackerel.io/ja/docs/entry/howto/install-agent/rpm
execute "install-mackerel-agent" do
command "curl -fsSL https://mackerel.io/file/script/setup-all-yum.sh | MACKEREL_APIKEY=#{mackerel_api_key} sh"
not_if "which mackerel-agent"
end
# install docker
# ref: https://docs.docker.com/engine/installation/linux/centos/#docker-ce
package 'yum-utils'
execute 'add-docker-repo' do
command <<-EOF
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum makecache fast
EOF
not_if 'which docker'
end
package 'docker-ce'
service 'docker' do
action [:enable, :start]
end
# VERSION: 1.11.2
# ref: https://docs.docker.com/compose/install/#alternative-install-options
execute 'install-docker-compose' do
command <<-EOF
curl -L https://github.com/docker/compose/releases/download/1.11.2/run.sh > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
EOF
not_if 'which /usr/local/bin/docker-compose'
end
Blog コンテナの作成
準備が整ったので、ブログを動かすためのコンテナを作成していきます。今回は Blog コンテナを定義する Dockerfile に加えて、 docker-compose を使ったオーケストレーションもやってみました。
Dockerfile
コンテンツを配信する Web サーバは Nginx を採用しました。 Nginx のコンテナは Docker Hub にて公式が配布しているものがあるのでそれを使いました。あとはドキュメントルートを掘ったりコンテンツを ADD したりしました。
FROM nginx:latest
# ブログコンテンツの設置
RUN mkdir -p /var/www/blog
ADD public /var/www/blog
# server ディレクティブが書かれた conf ファイルの設置
ADD config/nginx/conf.d/blog.conf /etc/nginx/conf.d/blog.conf
# SSL 証明書
RUN mkdir -p /etc/nginx/ssl
ADD config/nginx/ssl/fullchain1.pem /etc/nginx/ssl/blog.mizukmb.net.pem
ADD config/nginx/ssl/privkey1.pem /etc/nginx/ssl/blog.mizukmb.net.key
# start Nginx
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
CMD ["/usr/sbin/nginx", "-g", "daemon off;"] ですが、こちらは nginxをdockerで動かす時のTips 3選 - インフラエンジニアway - Powered by HEARTBEATS の『foregroudで起動する』を参考にしました。
ちなみに、 RUN と CMD の違いは、『docker build 時に実行されるのが RUN, docker run 時に実行されるのが CMD』のようです。
docker-compose.yml
あとは docker run すればいいだけなのですが、オプションでポートフォワーディングやログファイルが置かれたディレクトリにマウントしなければなりません。これが結構長くなってしまうので、この辺は docker-compose.yml を使って管理します。
数台の Docker コンテナを管理してこそ真価を発揮する docker-compose ですが、まあその辺は後でどうにかするということで…。
version: '2'
services:
blog:
build: .
ports:
- '80:80'
- '443:443'
volumes:
- /home/mizukmb/log/nginx:/var/log/nginx
ホストの 80, 443 ポートをそれぞれ Blog コンテナの 80, 443 ポートにフォワーディングしています。 また、Blog コンテナ内の Nginx ログ群をディレクトリマウントでホストサーバに収集しています。
コンテナ起動
Blog コンテナが定義された Dockerfile ごと docker-compose.yml で管理されているので、コンテナを起動するときは docker-compose コマンドを叩きます。
$ docker-compose up -d --build
-d はバックグラウンドで起動、 --build は docker build を実行するためのオプションです。
docker-compose ps や docker ps でコンテナの起動確認ができます。
$ docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
blogmizukmbnet_blog_1 /usr/sbin/nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
きどうしました!
所感
Docker で コンテナ作って運用してみたもののいまいち感動が得られませんでした。それよりもブログを引越した上に https 化もできたことのほうが個人的には嬉しかったです。
Docker で運用するにあたってはポートフォワーディングやディレクトリのマウントなどそれなりに考えることが増えて構築そのものはけっこう大変でした。 手軽にコンテナを作成・廃棄できるので、おそらく使い捨てしやすい点が魅力なんだろうなと思いました。
ブログの HTML ファイルなどをコンテナに含めるか、ホストサーバとマウントして共有にするかで悩みました。この辺りは Docker の性質を十分に理解していれば悩むところではないかも。実は今もよくわかってません。とりあえず状態を定義するという意味では ADD があってるのかなあと思ったのでそうしています。 このあたりは、使ってみて感覚をつかみたい。
ちなみに今回の引越しついでに本ブログの https 化も実施しました。 SSL 証明書は Let’s Encrypt で取得したのですが、 certbot を Dockerize した Docker コンテナが配布されていたのでそこから発行しました。詳しい手順は以下 URL を参照して下さい。
https://certbot.eff.org/docs/install.html#running-with-docker
今後
Docker と使えるようになったのとログを取れるようになったので
- ltsv 形式
- fluentd を動かすコンテナ
- SSL 証明書の自動更新(これも出来ればコンテナ作りたい)
あたりは挑戦したいなと思います。