kamalの仕組み
はじめに
業務でkamalを使ってdeployする機会があり、kamalの仕組みについてわかった気になったのでここに記そうと思います。
kamalのコマンドや詳しい設定についてこの記事では触れません。
そもそもkamalって何?
kamalは、ローカル環境でコンテナ内で動作しているアプリをそのまんまデプロイサーバーでも動作させるためのtoolです。kamalはローカルで動作しているdockerイメージをデプロイサーバーで利用することでローカル環境との差分が少なくなります。
railsでは従来のcapistranoというtoolが使われていました。こちらはかなり便利なのですが、デプロイサーバーのセットアップをしなくてはならず、サーバーをスケールさせる際に手間がかかりました。 例えば、自分でwebサーバーの設定をしたり、proxyの設定をしたり、データベースの設定などです。 (terraformを使えば解決するかもしれませんが。。。)
kamalの仕組み
さあ、ここからが本題です。
kamalは以下のような仕組みで動作します。
- ローカルでイメージをビルドしてコンテナレジストリにimageをpushする
- dockerがそもそもクロスコンパイルに対応しているのでどの環境でも動作するイメージを作成します。
- コンテナレジストリは私は今回GHCR(GitHub Container Registry)を使っています。(PATを用意しておく必要があります。)
- デプロイサーバーにsshで接続してdocker pullでイメージを取得する
- sshで接続してコンテナレジストリにあるimageを引っ張ってきます。
- imageをコンテナレジストリにpushしておくことによって、デプロイサーバーでビルドする必要がなくなり、デプロイサーバーに負荷がかかりません。
- docker runでコンテナを起動する
- kamalがdocker runでコンテナを起動します。
- kamal proxyでリクエストをルーティングする
- kamal 2からkamal proxyというリバースプロキシが導入されました。SSLの設定やゼロダウンタイムデプロイを担当します。
ざっとこんな感じです。
ここで私はkamal proxyは従来の構成でいうwebサーバー(Nginxなど)のようなものだと思いました。実際、リクエストを受け取ってアプリケーションに転送するという点では似ています。しかし、違いもあります。kamal proxyについて詳しく見ていきましょう。
kamal proxyはリバースプロキシである
kamal proxyはリバースプロキシとして動作します。リバースプロキシとは、クライアントからのリクエストを受け取り、背後にあるアプリケーションコンテナに転送する役割を担うものです。
kamal proxyの主な機能は以下の3つです:
- SSL終端: Let’s Encryptを使って自動的にHTTPS対応してくれます(※2028年にLet’s Encryptの証明書有効期間が90日から45日に短縮される予定なので、kamal-proxyが対応しているか今後チェックが必要です。現在、証明書有効期間についての設定項目が無いのでどうしようもないです。)
- ゼロダウンタイムデプロイ: 新しいコンテナが起動してヘルスチェックに通ってから、古いコンテナを停止します
- ヘルスチェック: コンテナが正常に動作しているか確認します
ただし、Nginxのようなwebサーバーとは違い、静的ファイルの配信やbasic認証の機能はありません。これらが必要な場合はアプリケーション側で実装する必要があります。
まとめ
kamalは小規模なアプリケーションにデプロイするのに最適なツールだと思いました。
雑すぎて申し訳ないです。