Rails8でKamal2導入されたけど実際どうなん？

Rails 8から新しく取り入れられた**Kamal2**。  
Dockerコンテナを使ったデプロイツールとして、従来のCapistranoなどとは違い、環境依存のトラブルをかなり減らしてくれるんです。  

この記事では、以下のポイントについて、やさしく解説していきますね。

- **Rails8でKamal2が導入されたけど、どうなの？**  
  → Kamal2の特徴や狙いをやさしく説明します
- **今までとの違いがわかる**  
  → 従来のデプロイツールとの違いをわかりやすく比較
- **設定方法がわかる**  
  → 設定ファイルの例と手順を紹介
- **使い方がわかる**  
  → 実際のデプロイワークフローとシーケンス図で解説
- **選ぶべきかどうかがわかる**  
  → 選ぶメリット、選ばないシチュエーション、そしてDockerコンテナを使う類似サービスとの比較もご紹介

---

## 1. Kamal2とは？

Kamal2は、Rails 8で初めて使われる**コンテナベースのデプロイツール**です。  
これまでのCapistranoのように、サーバーにSSHで接続してコマンドを実行するのではなく、**Dockerイメージを活用**してアプリの環境を一括管理してくれるので、環境の差異によるトラブルが起こりにくくなります。

- **環境依存の軽減**  
  アプリケーションをコンテナ化することで、開発環境と本番環境の違いを心配する必要がなくなります。
- **シンプルなワークフロー**  
  イメージのビルド、プッシュ、プル、コンテナ起動といった流れが自動化され、デプロイ作業がとてもスムーズになります。

---

## 2. これまでとの違い

### 従来のデプロイ手法（例：Capistrano）
- サーバーにSSHで接続して、ファイル転送やシンボリックリンクの切り替えなど、いろいろな作業を手動で行う必要がありました。
- サーバーごとの設定が複雑になりがちで、環境ごとの差異に悩まされることも多かったです。

### Kamal2のアプローチ
- **Dockerコンテナ**を使って、アプリケーションのビルドから起動までを一貫して管理します。
- 同じDockerイメージを使うことで、開発環境と本番環境で同じ動作を保証できます。
- 設定ファイルでサーバー情報や環境変数、ヘルスチェックの条件などをまとめて管理できるので、運用がシンプルになります。

---

## 3. ローカルマシンとKamal2 CLIの役割

- **ローカルマシン**  
  普段、コードを書いたりテストしたりするあなたのPCです。ここで、Kamal2 CLIコマンド（例：`kamal deploy`）を実行して、デプロイの指示を出します。

- **Kamal2 CLI**  
  ローカルマシン上で動く専用ツールです。  
  このCLIを使うと、Dockerイメージのビルドやプッシュ、リモートサーバーへのSSH接続が自動で行われるので、デプロイ作業がとても簡単になります。  
  つまり、**Kamal2 CLIはローカルマシン上で動いているツールであり、ローカルマシンそのものとは異なる存在**ということです。

---

## 4. 対象サーバーの具体例

Kamal2でのデプロイは、**Dockerが動作する環境ならどこでもOK**です。  
例えば、以下のような環境が利用できます。

- **AWSの場合**  
  AWS EC2インスタンスやECSクラスターで、Dockerコンテナとしてアプリを実行できます。
- **GCPの場合**  
  GCP Compute EngineやGKEクラスターで、同じくDockerコンテナを起動できます。

どちらも、基本的なプロセスは同じですが、各クラウドのセキュリティ設定やネットワーク設定は、それぞれの仕様に合わせる必要があります。

---

## 5. Kamal2の設定方法

Kamal2の設定は、プロジェクトのルートに作成される設定ファイル（例：`config/deploy.yml`）で管理されます。  
以下はその一例です。

```yaml
# config/deploy.yml
default: &default
  app_name: my_rails_app
  branch: main
  docker:
    build:
      context: .
      dockerfile: Dockerfile
  health_check:
    path: /health
    timeout: 10

production:
  <<: *default
  servers:
    - name: aws-prod
      host: ec2-1-2-3-4.compute-1.amazonaws.com
      user: deploy
      roles: [app, web, db]
      port: 22
  env:
    RAILS_ENV: production

staging:
  <<: *default
  servers:
    - name: gcp-staging
      host: 34.68.123.45
      user: deploy
      roles: [app, web]
      port: 22
  env:
    RAILS_ENV: staging
```

この例では、**production環境**はAWSのEC2、**staging環境**はGCPのCompute Engineを想定しています。  
各サーバーのSSH情報や役割、そして環境変数（例えば`RAILS_ENV`）がここで管理されています。

また、プロジェクトのルートには通常、以下のような**Dockerfile**も配置します。

```dockerfile
# Dockerfile
FROM ruby:3.1
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
CMD ["rails", "s", "-b", "0.0.0.0"]
```

---

## 6. Kamal2の使い方（ワークフロー）

Kamal2の基本的な流れは以下の通りです。

1. **ローカルマシンでKamal2 CLIを実行**  
   例：`kamal deploy` コマンドを実行してデプロイを開始します。

2. **Dockerイメージのビルドとプッシュ**  
   Kamal2 CLIがプロジェクトのDockerイメージをビルドし、指定のDockerレジストリにプッシュします。

3. **リモートサーバーへのSSH接続**  
   `config/deploy.yml`の設定を元に、リモートサーバーへSSH接続を確立します。

4. **サーバーでのDockerイメージのプルとコンテナ起動**  
   サーバーがDockerレジストリから最新イメージをプルし、新しいコンテナを起動します。

5. **ヘルスチェックとトラフィックの切り替え**  
   新しいコンテナが正常に起動しているかヘルスチェックで確認し、問題なければトラフィックを新コンテナに切り替え、古いコンテナを停止します.

### シーケンス図で見るKamal2のワークフロー

```mermaid
sequenceDiagram
    participant Dev as 開発者のローカルマシン
    participant CLI as Kamal2 CLI
    participant Reg as Dockerレジストリ
    participant Srv as サーバー (例: AWS EC2 / GCP Compute Engine)

    Dev->>CLI: Kamal2コマンド実行 (例: `kamal deploy`)
    CLI->>Reg: Dockerイメージをビルド＆プッシュ
    CLI->>Srv: SSH接続を確立（config/deploy.ymlの情報を元に）
    Srv->>Reg: Dockerイメージをプル
    Srv->>Srv: 新しいコンテナを起動
    Srv->>Srv: ヘルスチェック実施
    Srv->>Srv: トラフィックを新コンテナにルーティング
    Srv->>Srv: 古いコンテナを停止
```

---

## 7. Dockerコンテナを使う類似サービスとの比較

Kamal2はDockerコンテナを前提としたデプロイツールですが、他にもいくつか似たようなサービスがあります。  
ここでは、代表的なものとKamal2の違いを見てみましょう。

- **Dokku**  
  - 軽量なHerokuライクのPaaSとして、Gitプッシュで自動的にDockerイメージをビルド・デプロイします。  
  - シンプルな運用が魅力ですが、Kamal2はRails8に統合されており、設定ファイルで細かく環境を管理できる点が異なります。

- **Docker Swarm / Kubernetes**  
  - **Docker Swarm**はDockerが提供するオーケストレーションツールで、複数コンテナのクラスタ管理が可能です。  
  - **Kubernetes**は大規模なコンテナオーケストレーションプラットフォームで、スケーリングや自己回復機能に優れています。  
  - これらは非常にパワフルですが、設定や運用が複雑になりがちです。  
  - Kamal2は、シンプルなデプロイワークフローを重視しており、特にRailsプロジェクトにおいてはオーバーヘッドが少ない点が魅力です。

- **Capistrano（従来型）**  
  - Dockerを使わず、SSH経由でのデプロイが主流でした。  
  - 環境依存の問題が発生しやすく、設定が煩雑になりがちですが、Kamal2はコンテナによる一貫性を提供します。

---

## 8. Kamal2を選ぶべきかどうか & 選ばないシチュエーション

### Kamal2を選ぶメリット
- **一貫性とシンプルさ**  
  Dockerイメージを使い回すことで、開発環境と本番環境の違いによるトラブルが減り、リリース作業もシンプルに。
- **自動化されたワークフロー**  
  ビルド、プッシュ、プル、コンテナ起動、ヘルスチェックといったプロセスが自動化されるので、手間が大幅に軽減されます。
- **柔軟性**  
  AWSやGCPなど、さまざまなクラウド環境、さらにはオンプレミス環境でも利用可能なため、プロジェクトの規模やニーズに合わせて選べる点が嬉しいです。

### Kamal2を選ばないシチュエーション
- **既存のデプロイ環境が確立している場合**  
  すでにCapistranoなどで安定して運用している場合、移行コストや学習コストがネックになるかもしれません。
- **Dockerやコンテナ技術に不慣れなチームの場合**  
  コンテナ化のメリットは大きいですが、Dockerの知識が不足している場合は、最初の学習コストがかかることも。
- **レガシーなシステムやインフラの場合**  
  Dockerをサポートしていない古いインフラ環境では、Kamal2の導入が難しい場合があります。

---

## 9. まとめ

Kamal2は、Rails 8の新機能として登場し、Dockerを前提とした一貫性のあるデプロイワークフローを実現してくれます。  
**ローカルマシンでのKamal2 CLI実行 → Dockerレジストリ経由のイメージ管理 → 対象サーバー（AWS EC2、GCP Compute Engineなど）でのコンテナ起動**という流れで、シンプルかつ柔軟なデプロイが可能です。

環境依存のトラブルを減らし、効率的なリリースを目指す上でとても頼もしいツールですが、既存の環境やチームのスキルセット、さらには他のコンテナサービスとの比較も踏まえて、導入を検討してみてくださいね！

---

Happy Coding!  
何かご質問や不明な点があれば、ぜひコメントで教えてくださいね.