私が使っているVPSデプロイの神ツール Kamal2 入門ガイド

現在、私が使っているフルスタックフレームワークは主にNext.js 16とRails 8です。Railsを使うことで、公式推奨のデプロイツールKamalに触れる機会がありました。普段はRNとAlibaba Cloudサーバー上でプロジェクトをデプロイする際に使っています。使い勝手が良くシンプルなので、今回はKamal2の概念と入門的な使い方をご紹介しようと思います。
この記事では最初から難しい内容は扱いません。むしろ、Kamal2の最も核となる部分をわかりやすく説明したいと思います。具体的には、それが何か、私たちに何ができるのか、基本的な始め方、そして普段よく使う操作についてです。最後に、Next.jsのユースケースを紹介し、前述の概念を具体的なプロジェクトに落とし込む手助けをします。
Kamal2とは何か
一言でまとめると、Kamal2は **SSH + Docker を使ってアプリケーションをデプロイするためのツール** です。Herokuのような完全なプラットフォーム機能を提供するわけでもなく、Kubernetesのような重量級のオーケストレーションシステムでもありません。むしろ、「一連のDockerコンテナをデプロイする」という作業を、繰り返し実行可能なコマンドと設定としてまとめたものです。
Kamalの核となる考え方は非常にシンプルです:
ローカルに標準の
Dockerfileがある。config/deploy.ymlでデプロイ先とイメージ情報を記述する。SSH でサーバーに接続し、サーバー上で Docker 環境を準備する。
ローカルでイメージをビルドしてレジストリにプッシュし、サーバーにプルさせて実行する。
kamal-proxyで 80 番と 443 番ポートを受け持ち、新しいコンテナのヘルスチェックが成功したらトラフィックを切り替える。
これは私が Kamal を気に入っている点でもあります。余計な抽象化が少なく、何をしているのかがおおよそ理解できるので、問題が発生したときも調査しやすいです。
Kamal2 が適しているシーン
Kamal は次のようなケースに特に適していると思います:
すでに Docker でアプリケーションをパッケージ化している。
1台または数台の自分の Linux サーバーを持っている。
デプロイフローをできるだけシンプルに保ち、複雑なプラットフォームを維持したくない。
Rails、Next.js、さらには他の Web サービスでも同じデプロイ方法を使いたい。
言い換えれば、Kamal は Docker を「代替」するのではなく、Docker のデプロイをもっと使いやすくするためのものです。
まずはいくつかの基本概念を理解する
始める前に、Kamal で最も重要な概念をいくつか覚えておくことをお勧めします。
config/deploy.yml
これは Kamal のメイン設定ファイルで、デプロイ設定はここから読み込まれます。「今回のデプロイの説明書」のようなものです。サービス名、イメージ名、サーバーリスト、イメージレジストリ、環境変数、ビルダー、プロキシなどの内容がここに書かれます。
.kamal/secrets
これは secrets ファイルのデフォルトの場所で、Kamal はここから機密変数を読み取ります。例えば、イメージレジストリのパスワードや、Rails の RAILS_MASTER_KEY などは、通常 deploy.yml に直接ハードコードせず、.kamal/secrets を通じて注入します。
kamal setup
これは初回デプロイで最も重要なコマンドです。ドキュメントには明確に書かれていますが、サーバーに接続し、Docker がなければインストールし、イメージレジストリにログインし、イメージをビルド・プッシュ・プルし、kamal-proxy を起動し、新しいコンテナを起動し、GET /up が 200 OK を返した後にトラフィックを切り替えます。
kamal deploy
これはその後のリリースで最もよく使われるコマンドです。初回の setup が成功した後は、通常 kamal deploy でデプロイを完了します。
Kamal2 のインストール方法
ローカルにすでに Ruby 環境がある場合、最も直接的なインストール方法は次の通りです:
gem install kamalこれは公式ドキュメントで示されている標準的なインストール方法です。Ruby がない場合は、Docker 化された Kamal を実行することもできますが、公式ではこの方法にはいくつかの制限があると明記されているため、入門段階では gem インストールをお勧めします。
インストールが完了したら、バージョンを確認できます:
kamal versionプロジェクトの初期化
プロジェクトのディレクトリに移動し、次のコマンドを実行します:
kamal initこのコマンドは、Kamal に必要な基本ファイルを初期化します。最も重要なのは config/deploy.yml と .kamal/secrets です。
もしプロジェクトにすでに Dockerfile があれば、それは非常に重要な前提条件を満たしていることになります。Kamal のデフォルトのデプロイフローは、プロジェクトのルートにある標準的な Dockerfile を中心にイメージをビルドします。
最小限の設定
入門時は、まず小さな config/deploy.yml から始めることをお勧めします。公式ドキュメントの最小限の例は次のようなものです:
service: myapp
image: your-registry-user/myapp
servers:
- 203.0.113.10
registry:
username: your-registry-user
password:
- KAMAL_REGISTRY_PASSWORD
builder:
arch: amd64
env:
secret:
- AUTH_SECRETこの設定の中で、最初に理解すべき項目は以下の通りです:
service:必須。コンテナ名のプレフィックスとして使われます。image:イメージ名。最終的にレジストリにプッシュされます。servers:デプロイ先のマシンリスト。registry:イメージレジストリの設定。env.secret:secrets ファイルから読み込む必要がある環境変数。builder.arch:ビルドアーキテクチャ。ドキュメントの例では直接amd64が使われています。
この段階では、設定を完全にしようと追求せず、まずは基本的なパスが動くことを確認する方が重要です。
secrets の設定
次に .kamal/secrets を準備します。例:
KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
AUTH_SECRET=your-auth-secretRails プロジェクトの場合、ドキュメントの例では config/master.key から RAILS_MASTER_KEY を読み取ります。これも Rails と Kamal が自然に統合する理由のひとつです。Rails の新規プロジェクトはもともとこのデプロイ方法を導入しやすいからです。
初回デプロイで何が起こるか
設定と secrets の準備ができたら、次のコマンドを実行します:
kamal setupこのコマンドは多くのことを行いますが、「完全な初回デプロイ」と理解できます。公式ドキュメントによると、少なくとも以下のアクションを実行します:
SSH でサーバーに接続。
サーバーに Docker がなければ自動インストール。
ローカルとリモートでイメージレジストリにログイン。
プロジェクトルートの Dockerfile を使ってイメージをビルド。
イメージをレジストリにプッシュ。
サーバーにイメージをプルさせる。
kamal-proxyが 80/443 ポートで動作していることを確認。新しいコンテナを起動。
GET /upが200 OKを返すのを待機。トラフィックを新しいコンテナに切り替え。
古いコンテナを停止し、不要なイメージと停止したコンテナをクリーンアップ。
ここで非常に重要なポイントが一つあります。**ヘルスチェックのデフォルトは GET /up です**。そのため、アプリケーションにはこのような軽量なヘルスチェックエンドポイントを用意することをお勧めします。そうしないと、新しいコンテナが起動しても Kamal がトラフィックを切り替えてくれない可能性があります。
その後のデプロイはずっとシンプル
初回の setup が成功した後は、通常は次のコマンドを実行するだけで更新できます:
kamal deployドキュメントでは、これをその後のデプロイコマンドとして明確に指定しています。「通常のリリースエントリ」と考えてください。イメージの再ビルド、プッシュ、プル、新コンテナの起動、ヘルスチェック、トラフィックの切り替え、古いコンテナの停止を行います。
したがって、使用感としては、Kamal の最も快適な点は、初回デプロイで少し準備をすれば、その後は安定して動作することです。
よく使う操作
入門段階では、以下のコマンドが最も実用的です:
初期化
kamal initベースとなるデプロイファイルを生成します。
初回デプロイ
kamal setupサーバー、Docker、イメージ、プロキシ、アプリケーションを初めて一緒に立ち上げます。
その後のリリース
kamal deploy日常的に最もよく使うコマンドです。
マルチ環境デプロイ
後で staging と production を区別し始める場合、Kamal は -d で destination を指定できます。例:
kamal deploy -d staging公式ドキュメントによると、このとき Kamal は config/deploy.staging.yml を基本設定とマージして使用します。
この機能は非常に便利ですが、まだ入門段階であれば、存在を知っておくだけで十分で、すぐに使う必要はありません。
なぜ Rails と相性が良いのか
Rails 8 の新規プロジェクトには通常すでに Dockerfile が含まれており、Kamal のデプロイフローはまさに Dockerfile を中心に展開されます。さらに、Rails エコシステムはもともと Ruby gem のツールチェーンを自然に受け入れるため、Rails から Kamal に触れるのはほぼ自然な流れです。
私自身も、まず Rails プロジェクトでこの方法を見たからこそ、真剣に長期的に使えるデプロイソリューションとして Kamal を検討し始めました。
Next.js の入門ユースケース
最後に、私の日常に近い例を紹介します。Next.js プロジェクトを Kamal でデプロイする場合、通常は標準の Docker アプリケーションとして作成し、それを Kamal に任せてリリースします。
ステップ1:Next.js を standalone 出力にする
Next.js のドキュメントによると、output: 'standalone' を有効にすると、ビルド成果物として .next/standalone が生成され、デプロイと実行に必要な最小限のファイルと server.js が含まれます。これは Docker デプロイに非常に適しており、完全な開発環境をそのまま持ち込む必要がありません。
next.config.js には次のように記述できます:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
}
module.exports = nextConfig注意点として、Next.js のドキュメントでは、output: 'standalone' の実行方法は、生成された server.js を直接使う方が適切であり、next start を使い続けるべきではないとされています。
ステップ2:Dockerfile の準備
シンプルな Next.js の Dockerfile は次のようになります:
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]ここでのポイントは Docker のテクニックそのものではなく、考え方です。**まず Next.js を標準の実行可能なコンテナにし、その後 Kamal にデプロイを任せる** ということです。
ステップ3:Kamal 設定の記述
例:
service: my-next-app
image: your-registry-user/my-next-app
servers:
- 203.0.113.10
registry:
username: your-registry-user
password:
- KAMAL_REGISTRY_PASSWORD
builder:
arch: amd64
env:
clear:
PORT: 3000
NODE_ENV: productionこの設定のロジックは非常にシンプルです:
Kamal はサービス名を認識します。
Kamal はイメージをどこにプッシュすべきか認識します。
Kamal はどのサーバーにデプロイすべきか認識します。
コンテナ起動後、アプリケーションは 3000 番ポートで待機し、プロキシが外部トラフィックを受け付けます。
ステップ4:ヘルスチェックエンドポイントの追加
Kamal はデフォルトで GET /up をチェックするため、Next.js に最もシンプルなルートを追加します。例えば App Router の場合:
export async function GET() {
return Response.json({ ok: true })
}これを例えば app/up/route.ts に配置すると、/up がシンプルな成功レスポンスを返すようになります。このエンドポイントはできるだけ軽量であることが望ましく、目的は Kamal に「コンテナがトラフィックを受け付け可能です」と伝えることだけです。
ステップ5:デプロイ
最後に、Kamal の標準フローに戻ります:
kamal setupその後の更新:
kamal deployこのフローが Next.js プロジェクトで安定して動作するなら、次のことがわかります。Kamal はアプリケーションが Rails かどうかは気にしません。本当に重視しているのは、**標準の Docker イメージを提供できるかどうか、そしてヘルスチェックが可能な Web サービスを用意できるかどうか** です。
今回はここまで
もしあなたも私のように、まず Rails 8 で Kamal に触れ、徐々にこの方法を Next.js 16 プロジェクトに移行しているなら、Kamal2 の位置づけは非常に理解しやすいと思います。それはプラットフォームではなく、セルフホストの Docker デプロイをより秩序立てて行うためのツールです。
入門段階では、以下のことを押さえておけば十分です:
Kamal をインストールする。
設定ファイルを初期化する。
deploy.ymlと.kamal/secretsを理解する。kamal setupで初回デプロイができる。kamal deployでその後の更新ができる。ヘルスチェックがデフォルトで
GET /upに依存していることを知っている。
これらがスムーズに動くようになってから、マルチ環境、accessories、フック、複雑なプロキシ設定などを学ぶ方が自然でしょう。
Google でフォロー
HeyBinyang を Google の優先ソースに追加
Google から更新を見つけやすくしたい場合は、このサイトを優先ソースとして追加できます。
共有
共有
この記事を共有します。