Kamal2 運用の実際
16 June, 2025
Kamal2 運用の実際
オンプレミスの環境に Rails アプリケーションを構築することになった。もう数年、パブリッククラウドしか扱っていなかったので、だいぶ新鮮だった。Capistrano よりもだいぶスムーズに導入できたが、少しだけ手こずった部分を記録しておく。
構成
こういった構成で作った。
-
web (thruster 管理下)
- containers
- app
- job
- containers
-
db
- 自前運用の MySQL
-
frontend
- SSG で作ったコンテンツを置く(front の人が作る)
前提
- Rails8 api mode
- できるだけ 標準のデプロイ方式に寄せる
- データを SQL で参照できるようにする
- 既存の GUI で参照できるように
- sqlite の sync を意識したくない(後述)
- docker image は組織で既に管理しているリポジトリに格納する
- 関連する外部サービスのアカウント数を抑えたい
つまづいたところ
-
docker image repository
- 実際の動作
- ローカルで build + push
- デプロイ先が pull する
- ドキュメントを読まずに突き進んで、デプロイ失敗時の切り分けで困った
- 実際の動作
-
CodeDeploy は向かない
- ECR から CodeBuild + CodeDeploy したかった
- ローカルのハードウェアリソースやネットワーク帯域に依存したくなかった
- この構成は Kamal2 が想定しているプロセスに合っていなくて難しい
- ECR から CodeBuild + CodeDeploy したかった
-
ECR 環境で rake db:migrate だけを実行する方法
-
やりたいこと
- 先に db を後方互換な状態にしてから、アプリケーションを無停止でデプロイしたい
- 実際のコンテナ入れ替えは 1 回で済ませたい
- migrate だけの image を build -> push -> deploy -> migrate -> 変更を全部含んだ image build -> push -> deploy は大変なので
-
手順
-
リポジトリに image を push した状態で、デプロイプロセスを止める
-
latest image で rails db:migrate を実行する
-
container を入れ替える
-
-
コマンド
kamal build push kamal registry login kamal app exec --version (ECR image id) -i bash kamal app exec --version (ECR image id) rails db:migrate kamal deploy- kamal registry login が重要で、これでリモートが aws ecr login する
- これがないと、リモートで最新の image を pull できないままになる
- --version latest が動かなかった。原因不明。
-
-
kamal の volumes: にあるファイルの同期タイミング
-
SQLite でテストするとき、ファイルシステム上の実体ファイルが更新されなかった
-
container 側で close するまで変更が反映されなかった
-
アプリケーション側でこまめに対処するしかなさそう
-
sqlite3 ならこう
ActiveRecord::Base.connection.execute("PRAGMA wal_checkpoint(FULL);") -
job にして recurring.yml で動かすと手軽に解決できる
- ただ、solid_queue の失敗 job をすぐに解析したいときなんかは、結局この SQL を手で流すことになる。不便。
-
-
-
複数の物理ホストに Rails アプリケーションを分散できない
- thruster が管理できるのは 1 つの物理ホストのみ
- 仮想マシンベースの環境なら、少し大きめにメモリを割り当てないと