Kamal (旧MRSK) を使ったRailsアプリケーションのデプロイ戦略
Railsアプリケーションのデプロイには、HerokuやRenderのようなPaaS、Capistranoのようなデプロイスクリプト、あるいはCI/CDパイプラインからの手動デプロイなど、様々な選択肢があります。
近年、コンテナ技術(Docker)の普及に伴い、新しいデプロイの選択肢として注目を集めているのが、Railsの作者であるDHH氏が開発したKamal(旧名: MRSK)です。
Kamalは、Dockerコンテナ化したRailsアプリケーションを、任意のサーバー(クラウド、VPS、ベアメタルなど)に、非常にシンプルなコマンドでデプロイするためのツールです。
この記事では、Kamalがどのような問題を解決し、どのように機能するのか、そしてCapistranoやPaaSとは何が違うのかについて解説します。
Kamalとは?
Kamalのコンセプトは「コンテナのパワーを、PaaSのような手軽さで」です。
HerokuのようなPaaSは非常に手軽ですが、プラットフォームにロックインされ、インフラの柔軟性やコスト面に制約があります。一方、Capistranoは柔軟ですが、サーバーごとにRubyや依存ライブラリのバージョンを管理する必要があり、環境の差異に悩まされることがあります。
Kamalは、これらの問題点を解決します。
- Dockerによる環境のポータビリティ: アプリケーションはDockerイメージとしてビルドされるため、「開発環境では動いたのに本番環境では動かない」といった問題が起こりません。
- サーバーを選ばない: SSHでアクセスできるサーバーであれば、どこにでもデプロイできます。特定のクラウドプロバイダーに依存しません。
- シンプルな設定:
config/deploy.ymlという単一のYAMLファイルで、デプロイのすべてを定義します。 - ゼロダウンタイムデプロイ: 新しいバージョンのコンテナを起動し、ヘルスチェックが通ってからリクエストを切り替えるため、デプロイ中にサービスが停止することはありません。
Kamalの仕組み
Kamalのデプロイプロセスは、いくつかのシンプルなステップで構成されています。
- Dockerイメージのビルド: ローカルマシンまたはCIサーバー上で、
Dockerfileを元にアプリケーションのDockerイメージをビルドします。 - イメージのプッシュ: ビルドしたDockerイメージを、Docker HubやGitHub Container Registryなどのコンテナレジストリにプッシュします。
- サーバーへの接続:
config/deploy.ymlに定義されたデプロイ先サーバーにSSHで接続します。 - コンテナのプル: 各サーバーが、レジストリから新しいバージョンのDockerイメージをプルします。
- コンテナの起動: 新しいバージョンのコンテナを起動します。
- ヘルスチェック: 新しいコンテナが正常にリクエストを処理できる状態かを確認します。
- リクエストの切り替え: ヘルスチェックが成功したら、リバースプロキシ(デフォルトではTraefik)が、新しいコンテナにリクエストを振り向けるように設定を変更します。
- 古いコンテナの停止: 古いバージョンのコンテナを停止・削除します。
この一連の流れが、kamal deployという一つのコマンドで実行されます。
セットアップと使い方
1. インストール
kamal gemをインストールします。
gem install kamal2. 初期化
Railsアプリケーションのルートでkamal initを実行します。
kamal initこれにより、以下のファイルが生成されます。
config/deploy.yml: デプロイ設定ファイル。.env: 本番環境の環境変数やレジストリのパスワードなどを格納するファイル(.gitignoreに追加されます)。Dockerfile: Railsアプリケーションをコンテナ化するためのファイル。.docker/entrypoint.sh: コンテナ起動時に実行されるスクリプト。
3. config/deploy.ymlの設定
デプロイ設定ファイルに、アプリケーション名、デプロイ先サーバーの情報、レジストリ情報などを記述します。
# config/deploy.yml
service: my-rails-app
image: my-registry/my-rails-app
servers:
web:
hosts:
- 192.168.1.10
- 192.168.1.11
labels:
traefik.http.routers.my-app.rule: "Host(`www.example.com`)"
registry:
server: my-registry
username: my-username
password:
- KAMAL_REGISTRY_PASSWORD
env:
clear:
RAILS_MASTER_KEY: # .envから読み込むservice: アプリケーション名。image: プッシュ先のコンテナイメージ名。servers: デプロイ先サーバーのIPアドレスやホスト名を列挙します。registry: Dockerレジストリの認証情報。env: コンテナに渡す環境変数。
4. デプロイ
準備ができたら、deployコマンドを実行します。
kamal deployこれだけで、ビルドからデプロイまでの全プロセスが自動的に実行されます。
Kamalのその他の機能
- データベースやRedisの管理:
kamal mysql,kamal redisといったコマンドで、補助的なサービスもコンテナとして簡単にデプロイ・管理できます。 - 環境変数の管理:
kamal env pushで.envファイルの内容を安全にサーバーに転送できます。 - ログの閲覧:
kamal app logsで、全サーバーのアプリケーションログをストリーミング表示できます。 - コンソール/DBコンソールへのアクセス:
kamal app console,kamal db consoleで、稼働中のコンテナに対してRailsコンソールやDBコンソールを開くことができます。
まとめ
Kamalは、現代的なコンテナベースのデプロイを、Railsらしいシンプルさと手軽さで実現するツールです。
- PaaSの手軽さとIaaSの柔軟性を両立。
- Dockerによる環境の完全なポータビリティを実現。
config/deploy.ymlという単一ファイルでのシンプルな設定。- ゼロダウンタイムデプロイを標準でサポート。
小規模な個人プロジェクトから、複数のサーバーで構成される本格的なプロダクション環境まで、幅広いスケールに対応できます。
もしあなたが、PaaSの制約や、Capistranoでのサーバー環境管理に課題を感じているなら、Kamalは非常に魅力的な選択肢となるでしょう。Dockerの学習コストは必要ですが、それを乗り越えれば、クリーンで再現性の高い、モダンなデプロイフローを手に入れることができます。