前置き
一応、AWSにデプロイすることを想定しています
すでに手動デプロイが成功している前提で行います
構成
本番環境用にふたつ用意する
- docker-compose.production.yml
- Dockerfile.production
コンテナ内にキーを保存
ローカルで下記コマンドを実行し、キーをコピー。
ローカルで起動するコンテナにコピーすること
$ docker container cp ~/.ssh/<秘密鍵名> <コンテナ名>:/root/.ssh/<秘密鍵名>
コンテナ内で下記コマンドを実行し、EC2にログインできるか試す
$ ssh -i ~/.ssh/<秘密鍵> ec2-user@EC2IPアドレス
できたらおk
ローカル環境用のdocker-compose.dev.ymlに、キーを保存するよう記述
web:
# 省略
volumes:
- ~/.ssh:/root/.ssh
# 省略
Gem追加
group :development, :test do
...
gem 'capistrano'
end
docker-compose build
などでbundle install
をした後
コンテナ内で
bundle exec cap install
これでデプロイに必要なファイルが作られる
設定
Capfile
デプロイ先でコンテナを起動するだけなので、ここはいじらない
config/deploy/production.rb
server '××.××.×××.×××', user: 'ec2-user', roles: %w{web}
操作したいサーバは一つなのでrolesはwebのみで。
config/deploy.rb
# capistranoのバージョン固定
lock "~> 3.17.1"
# アプリ名
set :application, "test_app"
set :repo_url, "git@github.com:ユーザ名/リポジトリ名.git"
# ブランチ名
set :branch, "main"
# デプロイ先のディレクトリ。/var/www/のパターンも
set :deploy_to, "/home/ec2-user/test_app/"
set :ssh_options, {
# capistranoコマンド実行者の秘密鍵
port: 22,
keys: %w(~/.ssh/test_app_key.pem),
forward_agent: true,
auth_methods: %w(publickey)
}
set :docker_compose_path, "docker-compose -f docker-compose.yml"
set :RAILS_ENV, "RAILS_ENV=production"
namespace :deploy do
application = fetch :application
branch = fetch :branch
docker_compose_path = fetch :docker_compose_path
rails_env = fetch :RAILS_ENV
rails_compile = "#{docker_compose_path} run web rails assets:precompile #{rails_env}"
task :application_set_up do
on roles(:web) do
execute "cd #{application};" "git pull origin #{branch};" "#{docker_compose_path} down;" "docker system prune -f"
execute "cd #{application};" "#{docker_compose_path} build;" "#{rails_compile};" "#{docker_compose_path} up -d"
end
end
end
実行
コンテナ内でこのコマンドを実行
bundle exec cap production deploy:application_set_up
発展
config/deploy.rb
namespace :deploy do
...
tesk :タスク名 do
実行したい処理
end
end
bundle exec cap production deploy:タスク名
これで新しいタスクを作って実行できる。
ここで書かれた処理はコンテナ内ではなく、デプロイ先のサーバで実行されるものなので、そこを考慮したコマンドを書きましょう。