amakanをDocker化した感想

https://amakan.net/ のこの辺の改善の続き。


CIのビルドに時間が掛かるようになった

f:id:r7kamura:20170102230018p:plain
f:id:r7kamura:20170102230018p:plain

これはわりとしんどい。CircleCIのDockerのバージョンが古く、イメージのキャッシュをしづらいため、毎度新規にイメージをビルドしていることが原因。キャッシュが可能で、ビルド中にイメージを作成することができ、その作成したイメージでテストを実行でき、特定のブランチにおいてはそのままDockerレジストリにPushが可能で、環境変数の管理やチャットサービスとの連携が容易なサービスがあれば、それに乗り換えたい (Werckerとか?)。

デプロイしやすくなった

f:id:r7kamura:20170102225931p:plain
f:id:r7kamura:20170102225931p:plain

CircleCIでビルドされたイメージにそれぞれ番号 (タグ) が割り振られているので、その番号を指定すると、Amazon ECSが実行中のコンテナを数台ずつそのイメージに自動的に交換してくれる。なので、デプロイ時にやることとしてはDockerのタグを指定するだけとなった。わかりやすいので精神が楽になった。

ロールバックしやすくなった

コンテナの交換作業中に問題が起きた場合は、前のタグに戻すだけで前の状態に戻るようになった。配信する静的ファイルも全てイメージ内に置くようにしてあるので、その辺りも含めてすぐにロールバックできて嬉しい。

DBをMigrationしにくくなった

前までCapistranoを利用していて、デプロイ時に rake db:migrate が実行されるようにしていたが、これを自分でやる必要が発生した。まあCapistranoの場合でも、実行した直後 (からコードが切り替わるまで) にエラーが出ないように気を付ける必要があり、結局デプロイ前後どちらのコードでも新旧データベースに対応できるようにしつつ二度デプロイする必要はあったので、実際の差分としては「rake db:migrate を実行するコードを適当に自分で書く必要がある」ことぐらいだけど若干面倒。

ミドルウェアを変更しやすくなった

Node.jsはNode.js用のイメージ、RailsはRails用のイメージ、というように複数のミドルウェアが1つの環境に共存することがなくなったので、互いに影響する可能性を考慮する必要がなくなり、バージョン変更などが楽になった。また、イメージを構築するときも単純なシェルスクリプトを幾らか実行するコードを書くだけなので、気持ち分かりやすくなった。

マシン資源の管理がやりやすくなった

f:id:r7kamura:20170102225902p:plain
f:id:r7kamura:20170102225902p:plain

同じインスタンスで複数の (異なる種類の) コンテナを動かすことも容易になり、あまりお金をかけられない個人開発でも手軽に節約できるようになった (手軽ではない節約方法は沢山ある)。例えばRubyのバージョンを上げるときでも、SidekiqはRuby 2.3 、Pumaは Ruby 2.4という構成にすることもできる。SidekiqとPumaが1プロセスずつ動くと、それぞれ250MBずつで合計500MB。デプロイ時にイメージを交換するために1コンテナ余分に動かすことを考えて、メモリが1GBあるインスタンスを利用しよう、という具合でリソースを管理できる。結果的にちょっとサーバ代が浮いた。

ALBが高い

浮いたサーバ台がちょうど相殺されてしまった……。

Docker for Macの時刻がずれる

スリープしてるとDocker for Macの時刻が遅れてしまう。TerraformをDocker経由で実行するようにしているので、AWSのAPIを利用するときに署名に含めるタイムスタンプが古すぎてエラーになることがある。これはDocker for Macを再起動すれば直る。そもそも手元からTerraformを動かすより、CIで動かすようにしたほうが良さそう。

SSHが不要になった

実行中のサーバにSSH接続してローリングデプロイするようなことが無くなったので、SSHが不要になった。鍵の管理が必要なくなってだいぶ楽。

検証環境や別サービスがつくりやすくなった

似た構成のテスト用環境をすぐにつくれるようになったのが便利で、staging環境をつくれた。あと別のサービス用に似た構成をつくるときに、コードを真似て簡単に始められるようになったので気持ちが楽。