Heroku Container Registryをつかってみたよ
こんにちは。先日、とある勉強会でHerokuを使ったデモを行いましたので、それに関連しての覚書を貼っておきます。
Herokuでコンテナ形式でアプリケーションをデプロイしてみた
デモに使っているのはRedmineというRuby on Railsのプロジェクト管理・チケット管理システムです。
わたしが作っているのは、プラグインという形で差し込める一部のものです。
このため、そもそも動かすにはRedmineのソースコードが必要になります。
ただし、わたしはRedmine本家のリポジトリのOwnerではないし、RedmineのリポジトリをフォークしてHerokuのリポジトリにプッシュするやり方だと、ソースコードが非常に大きくなって扱いきれません。
また、本家Redmineの変更にも追従し続けないといけないという点が悩ましくなります。
そこで今回使ったのが、Dockerのイメージを作ってHeroku側にpush。
このイメージからコンテナを起動して、デモサイトを立ち上げるという方式です。
こんな流れになります
1. 通常のHerokuにソースをpushするパターン
まずHerokuでの初めの一歩としては、herokuコマンドでアプリケーションを作成し、受け皿を作成します。
そこに対してソースコードをpushすると、Heroku側のGitリポジトリに登録されつつ、デプロイが実施される形になります。(だいぶ端折っていたり、誤りがあるかもしれませんので、その際はご指摘いただければ幸いです)
順番としては、push -> Heroku側でちゃんとビルドしデプロイが可能なものかどうかを確認 -> 問題なければデプロイ&Heroku側のGitにも登録完了という感じになります。つまり、うまくデプロイできる状態のソースでないと、Heroku側でpushを受け付けてくれません。
2. Dockerイメージをpushするパターン
Heroku側でビルドをするのではなく、手元でDockerfileを使ってイメージをビルドし、Heroku側のレジストリに登録します。
そのあとに、アプリケーションのリリースという操作で、イメージからコンテナを起動する形になります。
実は、1のパターンも、実際はコンテナベースでアプリケーションが起動しています。裏側でイメージがビルドされており、うまくビルドできたらコンテナとして起動する流れになっています。
ただし、この方法だと、開発する側がDockerについて何も知らなくても問題なく、Heroku側がよしなにやってくれる形になります。
違いはあるの?dynoの動きを確認
1, 2ともに試してみると、コマンドラインインタフェースやGUIでの操作については、ほぼ差がないように感じました。
Railsアプリケーションに関して言えば、bashもrails consoleもどちらも同じく利用できます。
さらに、実は、1のパターンでも「実際はコンテナ」ということは理解していなかったので、あえて今回は「本当にそう?」なのか確認してみることにしました。
Webが起動している状態で、heroku run bash -a アプリケーション を実行し、シェルにアクセス。
そこで内部のログ用ディレクトリにログが出ていないことを確認。
この時点で、webとして上がっているコンテナとしては別ものとしてアクセスしているというのがわかります。
次に、アプリケーションのソースコードがあるディレクトリで、rm -fr * を実施。
ソースコードは綺麗さっぱり無くなります。
(以下はHerokuの管理画面からbashを起動し、アプリケーションのディレクトリの中身を消してみたキャプチャです)
その上で、再度 heroku run bash -a アプリケーション を実行しシェルにアクセスすると、なにごとも無かったようにソースが存在しています。
つまり、pushした時点のイメージから、コンテナとして都度起動しているというのを実感した次第です。
どっちのほうがよさそう?
Redmineのケースのように、他のシポジトリからのソースが必要、そのための起動用の環境が必要...という場合は、わたしは後者のDockerイメージを利用するほうがいいなと感じました。
今回は、Dockerイメージのビルドとpushは、手元でのコマンドラインからか、CI (CircleCI) を利用したのですが、Heroku自身の機能を使ってHeroku側でDockerイメージをビルドすることもできます。
まだ試していないので、こちらもやってみようと思います。
たくさんの記事の中で、目に留めてくださってありがとうございます! 気に入っていただけたら嬉しいです!