この記事は ConoHa Advent Calendar 2016の 8 日目の記事です。
こんにちは、keika299 です。
前年度は Mail API について書いたらネタ被りさせてしまいました。ごめんなさい。
でも今年も他の方の事とかあんまり考えてないんで、また被ったら来年も謝る方向でいきます。
さて、今日のテーマはこちら。
ConoHa で Docker コンテナを自動デプロイする
一昨年くらいから流行ってますからね。コンテナ。
で、作ってる Web アプリケーションをコンテナ化したところまではいいんですが、
デプロイどうやってやろうかと。
これまでは、rsync 使って、CI からサーバーに放り込んでたんですが、
なんかこう、githubにコードをプッシュするだけでシューって上手いことなって
かっこいい感じでデプロイされるようにしたいなって。思ったんですよね。
実際にサービスをどのようにつなげるか考える
最初の計画
github に push したら、Webhook で DockerHub で Build が走り、
完成したら ConoHa の実環境にデプロイ。
デプロイ完了の通知を Slack 経由で受け取る。と。
OK、いい感じじゃん。これで行こうか。
って思ったんですが、問題点がありまして。
どうやって Docker コンテナの更新を実現させる?
この部分。
Docker Hub でのコンテナビルドが成功したら、それを検知して ConoHa サーバー上で
更新するプログラムを回さないとならんのですね。
コンテナビルドの完了自体は Docker Hub が完了時に Webhook を飛ばしてくれるので良いとして、
問題は「誰が Webhook を受け取るのか?」と言うことになります。
このあたりは、AWS等ではコンテナビルド完了にフックして自動的にコンテナを更新
(しかも Blue-Green Deployment なので無停止)してくれるサービスがあるので、
そういったサービスを利用されている方には無縁の話かもしませんが。
救いの手が差し伸べられた。
で、AWS Lambda みたいなサービスを使って更新することも考えていたのですが、
そんな時に ConoHa 様からこんなお知らせが。
「512 MB プラン、始めました。」
どうせ Webhook で走らせるものは基本軽い処理なのですから、
月々 630 円でサーバー立てられるなら使わない手はないですよね? ね?
で、結局の所の構成は
こんな感じで、 Webhook 用サーバー(ConoHa 512 MBプラン)を仲介するようにしました。
環境を作るぞよ
ここで話さないこと
GitHub -> Docker Hub の連携
Docker Hub から簡単に連携させられますヨ。
ConoHa サーバーのセットアップについて
SSHとかファイアウォールとかの設定があるけど、ここもパス。
誰かが書いてくれるんじゃぁないかな。(適当)
今回はサービス提供側のサーバーで Docker Composeを使うので、
Docker Engine と Docker Compose のインストールもしといてね。
Docker Compose の使い方
公式みて。
今回の想定構成は
version: '2'
services:
target-service:
image: example/target-repo:latest
links:
- another-service
another-service:
image: example/another-repo:latest
Webhook サーバーを立てる
Webhook に使えるサーバーは探せばゴロゴロ出てきそうだが、
個人的に Go 言語の復習をしたかったので、簡単なのを書いた。
とりあえずソースだけ githubの keika299/crocop に置いときます。
こんな感じの
version: 1
port: 8080
hooks:
- webhook-name:
handle: /webhook-handle-url-here
script: /script/file/path.sh
設定ファイルを本体と同じ場所に置いといて、./crocop start
で走らせると
http://example.com/hook/webhook-handle-url-here
へのアクセスで
/script/file/path
を実行するようにしています。
dockerが置いてあるサーバーの更新を走らせる
スクリプトファイルは更新したいサーバーへsshで接続してそちらのスクリプトを走らせたのち、
slackへwebhookを飛ばせばOKなので
#!/bin/sh
set -e
ssh -i ~/.ssh/server-ssh-key -p 22 username@servername /docker/update/shell/path
curl -X POST --data-urlencode 'payload={"channel": "#target-channel", "username": "webhookname", "text": "Updated docker container.", "icon_emoji": ":whale2:"}' https://hooks.slack.com/services/example
こんな感じ。
ほんとはsshの所で、リモート先でエラーが出たらきちんと終了させて、とかするべきなんだけど
その辺はご自分で頑張ってって感じで。
dockerが置いてあるサーバー側で更新をかける
先ほどsshで走らせる指定をしたシェルを、dockerがある側のサーバーに実際に作る。
今回はdocker-composeを使っているので、
#!/bin/sh
set -e
docker pull example/target-repo:latest
docker-compose -f /path/to/docker-compose.yml down --remove-orphans
docker-compose -f /path/to/docker-compose.yml up -d
単純にpullしてから強制的に更新かけてる。
手で更新かけるときに打つコマンドをそのまま放り込んだ。
docker hub に webhook を登録
終わりが見えてきた。
最後に、docker hub に行って、webhook を設定する。
ちなみに、githubとかと連携して automated builds にしておかないと
webhook は設定できない。注意 。
webhook の URL は最初の方で設定した
http://example.com/hook/webhook-handle-url-here
を指定する。
完成!
あとは github にプッシュしたら、思い描いていた感じでちゃんとビルド -> 通知までやってくれる。
+αのネタとして
とりあえず今回は Docker の自動デプロイがしたかっただけだったのだけど、
蓋を開けて見たら webhook サーバーを自前で持つ結果となった。
最近のwebサービスはhttpで色々やり取りできるから、
好きなようにwebhookを走らせられるのは結構便利な気がする。
(slackもpayloadいじると設定変えられるので、このwebhookサーバーを仲介するとintegration枠1つだけでたくさんのサービスの通知をやり取りできる。とか。やっていいのか知らんけど。)
512 MBプランで十分だし、IoTとかで需要も伸びそうだし、
みんなで ConoHa の 512 MBプランを契約してwebhookサーバー作って、
ちょっとずつ、このは様に 搾取されて 貢献 できればいいんじゃないかな。
〆
長くてごめんね。歳をとると話が長くなるそうです。
去年はAPIネタ、今年は新しくリリースされた 512 MBプランの使い方の一つについてのネタで書かせてもらいました。
気が早いですが、来年のアドベントカレンダーではどんな新サービスについて書けるかなーって、
とっても楽しみですね。