今回は、”Kamal2″ を使用してデプロイされた Rails8のアプリケーションにおいて、git の管理下に置いていない(.gitignore に含まれる)ファイルを本番環境へ転送する手順を紹介します。
機密情報を含む設定ファイルや、一時的に必要な初期データファイルなど、Git リポジトリに含めずに本番環境でのみ利用したいファイルがある場合に役立ちます。
転送の全体像
転送作業は、大きく以下の 2 段階で構成されます。
- (1)scp コマンドによる一時的なファイル転送
ローカル環境から本番環境サーバーの任意のディレクトリへ対象ファイルを転送します。 - (2)docker cp コマンドによるコンテナ内へのファイル移動
サーバー上に転送されたファイルを、実際に動作しているアプリケーションコンテナの所定のディレクトリへコピーします。
scp コマンドで本番環境サーバーへファイルを転送する
まず、ローカル環境から本番環境のサーバーへファイルを一時的に転送します。
例えば、ローカルの db/seeds.rb ファイルを、
本番環境の deploy ユーザーのホームディレクトリ配下にある隠しディレクトリ
.kamal へ転送する場合、以下のコマンドを実行します。
% scp db/seeds.rb deploy@<本番環境のサーバーIPアドレス>:/home/deploy/.kamal
- db/seeds.rb: 転送したいローカルのファイルパス
- deploy: 本番環境サーバーのユーザー名
- <本番環境のサーバーIPアドレス>: サーバーの IP アドレスまたはホスト名
- /home/deploy/.kamal: サーバー上の一時的な転送先ディレクトリ(任意の場所でOK)
転送したファイルをアプリケーションコンテナへ移動する
サーバー上に転送したファイルを、現在動作中のアプリケーションコンテナ内にコピーします。
この作業には、対象のコンテナを特定するための コンテナ ID が必要になります。
コンテナ ID の確認
本番環境のサーバーに SSH 接続し、docker ps コマンドで稼働中のコンテナ一覧を確認します。
$ docker ps
出力された一覧から、ご自身のアプリケーション名に対応するコンテナ(例: アプリケーション名-web-xxxxxxx)の CONTAINER ID をコピーします。
例では、「ed77db77c777」が該当します。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed77db77c777 ghcr.io/Githubのユーザ名/アプリケーション名:xxxxxxx "/rails/bin/docker-e…" 3 days ago Up 3 days 80/tcp アプリケーション名-web-xxxxxxx
5555bd5fd555 basecamp/kamal-proxy:v0.9.0 "kamal-proxy run" 2 weeks ago Up 4 days 0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp kamal-proxy
docker cp コマンドによるコンテナ内へのコピー
次に、docker cp コマンドを使用して、サーバー上の一時ディレクトリに置いたファイルを、
アプリケーションコンテナ内の目的のディレクトリへコピーします。
$ docker cp /home/deploy/.kamal/seeds.rb コピーしたコンテナID:/rails/db/
- /home/deploy/.kamal/seeds.rb: サーバー上の一時ディレクトリにある転送元ファイル
- コピーしたコンテナID: アプリケーションコンテナの ID
- :/rails/db/: コンテナ内のコピー先パス(Rails アプリケーションの標準的な /rails ディレクトリ以下を指定)
成功すると、以下のような出力が表示されます。
Successfully copied 17.9kB to コピーしたコンテナID:/rails/db/
これで、git 管理下にないファイルが本番環境のアプリケーションコンテナ内に配置されました。
補足
データベースへの初期データ投入
上記の例のように seeds.rb を転送し、seeds で設定した初期データを DB に登録したい場合は、docker exec コマンドでコンテナ内で rails db:seed を実行します。
$ docker exec コピーしたコンテナID bin/rails db:seed
コンテナのシェルに入る
コンテナ内で詳細な操作を行いたい場合は、以下のコマンドでコンテナのシェルに直接入ることができます。
$ docker exec -it コピーしたコンテナID bash
感想
私自身、この「Git 管理外のファイルを本番環境のコンテナへ安全に転送する」というシンプルなタスクを実現するまでに、実はかなりの時間を要した。
Kamal が提供するデプロイ環境の特性上、従来のデプロイの手順とは異なるアプローチが必要になるため、初めは手探りの状態だった。
試行錯誤の末、この scp と docker cp を組み合わせるという手法に辿り着いたものの、この手順が明確にまとめられた日本語の情報が少なかったため、「同じ壁にぶつかっている方の助けになれば」という思いで本記事の執筆に至った。
この情報が、Kamal を利用されているエンジニアの皆様のデプロイ作業の効率化に貢献できれば嬉しい。
