更新日:
【Rails】 Capistranoを使ってデプロイを自動化しよう
Capistranoというgemは面倒なデプロイ作業を自動化してくれるツールです。面倒なデプロイ作業もコマンド一つで行うことができます。
AWSのEC2を使ってデプロイをする際、非常に多くの手順を踏む必要があります。
それをコマンド1つで行ってくれるのが自動デプロイツールです。
その自動デプロイツールで人気があるのはCapistranoというgemです。
この記事ではAWSのEC2でNginxとUnicornを使った際のCapistranoの導入方法について解説していきます。
※EC2でのデプロイ方法については【Rails】 AWSのEC2でRailsのアプリをデプロイしようの記事を参照ください
自動デプロイツールとは
デプロイの記事でも解説した通り、AWSのEC2サービスでRailsアプリのデプロイを行うには下記の手順が必要です。
- EC2インスタンスにSSH接続をする
- EC2インスタンスにpullする
- アセットのコンパイルをする
- Unicornの再起動をする
といったようにデプロイの度にEC2インスタンスに接続したり、Unicornの再起動をしたりと、とても面倒です。
これをローカルのターミナルのたった一つのコマンドで行ってくれるのが自動デプロイツールです。
導入することによって簡単になることはもちろん、コマンドの打ち間違いによるミスなどもなくなるので、デプロイ自体がとても信憑性のあるものになります。
Capistranoを導入しよう
この章では自動デプロイツールの一種であるCapistrano(カピストラーノ)というgemの導入方法を解説していきます。
gemをインストールしよう
Capistranoを導入するにはgemをインストールする必要があります。
Gemfileの開発環境の部分を下記のように編集します。
1
2
3
4
5
6
7
group :development do
gem 'capistrano'
gem 'capistrano-rbenv'
gem 'capistrano-bundler'
gem 'capistrano-rails'
gem 'capistrano3-unicorn'
end
Capistrano以外にもgemを追加しています。
gem名 | 役割 |
---|---|
capistrano-rbenv | Capistranoでrbenvでインストールしたrubyを使用可能にする |
capistrano-bundler | Capistranoで自動でbundle installを可能にする |
capistrano-rails | Capistranoでマイグレーションやアセットのコンパイルを可能にする |
capistrano3-unicorn | CapistranoでUnicornの再起動などを可能にする |
そしてbundle installコマンドでインストールします。
次に下記のコマンドを実行します。
1
2
3
4
5
6
7
8
9
% bundle exec cap install
# ファイルが作成される
mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
create Capfile
Capified
このコマンドを実行することにより下記のようなファイルが作成されます。
1
2
3
4
5
6
7
8
9
10
アプリケーション名
├── Capfile
├── config
│ ├── deploy
│ │ ├── production.rb
│ │ └── staging.rb
│ └── deploy.rb
└── lib
└── capistrano
└── tasks
次に作成されたファイルの編集を行います。
Capfileを編集しよう
Capfileはインストールしたgemの中からCapistranoで読み込むgemを指定するファイルです。
デフォルトだと下記のようになっています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Load DSL and set up stages
require "capistrano/setup"
# Include default deployment tasks
require "capistrano/deploy"
# Load the SCM plugin appropriate to your project:
#
# require "capistrano/scm/hg"
# install_plugin Capistrano::SCM::Hg
# or
# require "capistrano/scm/svn"
# install_plugin Capistrano::SCM::Svn
# or
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails
# https://github.com/capistrano/passenger
#
# require "capistrano/rvm"
# require "capistrano/rbenv"
# require "capistrano/chruby"
# require "capistrano/bundler"
# require "capistrano/rails/assets"
# require "capistrano/rails/migrations"
# require "capistrano/passenger"
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
呼び出すgemを指定するため、Capfileを下記のように全て書き換えましょう。
1
2
3
4
5
6
7
8
9
10
require "capistrano/setup"
require "capistrano/deploy"
require "capistrano/rbenv"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
require "capistrano3/unicorn"
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
deploy.rbを編集しよう
次はconfigフォルダ
に作成されたdeploy.rb
を編集します。
このファイルはデプロイ時に行われるタスクを設定するファイルです。
デフォルトだと下記のように記述されています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# config valid for current version and patch releases of Capistrano
lock "~> 3.16.0"
set :application, "my_app_name"
set :repo_url, "git@example.com:me/my_repo.git"
# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# Default deploy_to directory is /var/www/my_app_name
# set :deploy_to, "/var/www/my_app_name"
# Default value for :format is :airbrussh.
# set :format, :airbrussh
# You can configure the Airbrussh format using :format_options.
# These are the defaults.
# set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
# append :linked_files, "config/database.yml"
# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for local_user is ENV['USER']
# set :local_user, -> { `git config user.name`.chomp }
# Default value for keep_releases is 5
# set :keep_releases, 5
# Uncomment the following to require manually verifying the host key before first deploy.
# set :ssh_options, verify_host_key: :secure
これを参考に編集していきます。
デフォルトの記述を下記のように全て書き換えましょう。
2、5、6、14、22行目の部分はご自身のものに差し替えてください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# Capistranoのバージョンを指定(初期から記入済み)
lock 'Capistranoのバージョン'
# アプリケーションの指定
set :application, 'レポジトリ名'
set :repo_url, 'git@github.com:Githubのユーザー名/レポジトリ名.git'
# sharedディレクトリに入れるファイルを指定
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "vendor/bundle", "public/system", "public/uploads"
# SSH接続設定
set :ssh_options, {
auth_methods: ['publickey'],
keys: ['~/.ssh/プライベートキーの名前.pem']
}
# 保存しておく世代の設定
set :keep_releases, 5
# rbenvの設定
set :rbenv_type, :user
set :rbenv_ruby, 'アプリで使用しているrubyのバージョン'
# ここからUnicornの設定
# Unicornのプロセスの指定
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }
# Unicornの設定ファイルの指定
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
# Unicornを再起動するための記述
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:restart'
end
end
Capistranoのバージョンがわからない場合はGemfile.lock
で調べましょう。
差し替える例は下記の通りです。
(例)
Capistranoのバージョン: 3.16.0
レポジトリ名: pikawaka
Githubのユーザー名: miyagima
プライベートキーの名前: pikawaka
アプリで使用しているrubyのバージョン: 2.6.5
1
2
3
4
5
6
7
8
lock "3.16.0"
set :application, 'pikawaka'
set :repo_url, 'git@github.com:miyagima/pikawaka.git'
keys: ['~/.ssh/pikawaka.pem']
set :rbenv_ruby, '2.6.5'
production.rbを編集しよう
configフォルダ
内に作成されたdeployフォルダ
内には本番環境でのデプロイ設定をするproduction.rb
とステージング環境でのデプロイ設定をするstaging.rb
という2つのファイルが作成されています。
こちらは環境別に設定するファイルになります。
今回は本番環境のデプロイ設定を行うのでproduction.rb
を編集します。
1
server 'Elastic IPアドレス', user: 'ec2-user', roles: %w{app db web}
上のElastic IPアドレス
の部分はご自身のものを入力してください。
(例)Elastic IPアドレスが「12.345.67.89」だった場合
1
server '12.345.67.89', user: 'ec2-user', roles: %w{app db web}
ディレクトリ構成を把握しよう
先ほどdeploy.rb
の記述内に「sharedディレクトリに入れるファイルを指定」というのがありました。
「sharedディレクトリ」とはCapistranoの自動デプロイ時に本番環境のディレクトリに新しく自動で追加されるディレクトリの1つです。
自動で作成されるディレクトリはこれを含めて3つあるので確認しておきましょう。
ディレクトリ名 | 役割 |
---|---|
current | 現在デプロイされている内容が保管されている |
releases | 過去にデプロイした内容が保管されている |
shared | バージョンに関係なく参照される内容が保管されている |
自動デプロイ作業によりディレクトリ構成が変化するので、それに応じて変更するファイルがあります。
Nginxの設定を編集しよう
まずはNginxの設定ファイルを編集します。
EC2インスタンスに接続し、EC2のターミナルで下記のコマンドを実行し、rails.confファイル
を編集モードにしましょう。
1
[ec2-user@ip-172-12-34-5 ~]$ sudo vim /etc/nginx/conf.d/rails.conf
ファイルの中身が表示されたらi
キーを押してINSERTモードにします。
そして下記のように3行目と10行目のコードを編集しましょう。
※記述内容はAWSのEC2でRailsのアプリをデプロイしようの記事内のコードを参照しています
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
upstream unicorn {
// shared内に変更
server unix:/var/www/クローンするリポジトリ名/shared/tmp/sockets/unicorn.sock;
}
server {
listen 80;
server_name ご自身のElastic IPアドレス;
// current内に変更
root /var/www/クローンするリポジトリ名/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
try_files $uri/index.html $uri @unicorn;
error_page 500 502 503 504 /500.html;
}
フォルダ構成の部分を編集したらescキー
を押してINSERTモードから抜けましょう。
その後、:wq
と入力しenterキー
を押して編集モードから抜けます。
unicorn.rbを編集しよう
次にUnicornの設定ファイルであるunicorn.rb
を編集します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# rootパスのディレクトリを指定(「../」が先頭に追加)
root_path = File.expand_path('../../../', __FILE__)
# アプリケーションサーバの性能を決定する
worker_processes 2
# アプリケーションの設置されているディレクトリを指定(current内に変更)
working_directory "#{root_path}/current"
# プロセスIDの保存先を指定(shared内に変更)
pid "#{root_path}/shared/tmp/pids/unicorn.pid"
# ポート番号を指定(shared内に変更)
listen "#{root_path}/shared/tmp/sockets/unicorn.sock"
# エラーのログを記録するファイルを指定(shared内に変更)
stderr_path "#{root_path}/shared/log/unicorn.stderr.log"
# 通常のログを記録するファイルを指定(shared内に変更)
stdout_path "#{root_path}/shared/log/unicorn.stdout.log"
# 以下略
これで準備は完了です。
今までの編集を反映させるため、commitしGitHubへpushしましょう。
自動デプロイをしてみよう
この章では実際に自動デプロイをする流れを解説していきます。
設定ファイルを色々と変更したので、Nginxの再起動をします。
1
2
[ec2-user@ip-172-12-34-5 ~]$ sudo systemctl reload nginx
[ec2-user@ip-172-12-34-5 ~]$ sudo systemctl restart nginx
またデータベースが起動しているか念のため確認しておきます。
1
2
3
4
5
6
7
8
[ec2-user@ip-172-12-34-5 ~]$ sudo systemctl status mariadb
● mariadb.service - MariaDB database server
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled)
Active: active (running) since 土 2021-05-29 23:31:10 UTC; 4 days ago
Main PID: 6514 (mysqld_safe)
CGroup: /system.slice/mariadb.service
├─6514 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
└─6680 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log...
「Active: active (running)」となっていれば問題ありません。
起動していなかったら下記のコマンドでデータベースを起動しましょう。
1
[ec2-user@ip-172-12-34-5 ~]$ sudo systemctl start mariadb
自動デプロイコマンドを実行しよう
それでは自動デプロイを行います。
ローカルのターミナルから下記のコマンドを実行します。
1
% bundle exec cap production deploy
するとデプロイが始まり下のようなログが出力されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
00:00 git:wrapper
01 mkdir -p /tmp
✔ 01 ec2-user@18.123.148.102 0.087s
Uploading /tmp/git-ssh-c28cb931191aa47e7611.sh 100.0%
02 chmod 700 /tmp/git-ssh-c28cb932291aa47e7611.sh
✔ 02 ec2-user@18.123.148.102 0.099s
00:00 git:check
01 git ls-remote git@github.com:********/******.git HEAD
01 84fdc5b49f9ab467d2834a6eded8bdaa11ec284b HEAD
✔ 01 ec2-user@18.123.148.102 2.136s
00:02 deploy:check:directories
01 mkdir -p /var/www/*******/shared /var/www/*******/releases
✔ 01 ec2-user@18.123.148.102 0.084s
00:02 deploy:check:linked_dirs
01 mkdir -p /var/www/*******/shared/log /var/www/******/shared/tmp/pids /var/www/******/shared/tmp/cache /va…
✔ 01 ec2-user@18.123.148.102 0.089s
00:02 git:clone
The repository mirror is at /var/www/******/repo
00:03 git:update
01 git remote set-url origin git@github.com:*******/*******.git
✔ 01 ec2-user@18.123.148.102 0.093s
02 git remote update --prune
02 Fetching origin
02 From github.com:******/******
02 161aad2..84fdc5b master -> master
✔ 02 ec2-user@18.123.148.102 2.351s
(以下省略)
途中でエラーが発生していなければ自動デプロイ完了です。
エラーが発生している場合はもう一度編集し忘れている箇所がないか、commitやpushのし忘れはないか確認してみましょう。
その後、ブラウザで更新内容が反映されているか確認をし、反映されていれば自動デプロイ完了です。
今後も下記の手順で自動デプロイを行います。
- アプリを編集する
- commitをする
- ブランチを切っている場合はmergeする
- GitHubのmasterブランチへpushする
- ローカルのターミナルで自動デプロイコマンドを打つ
エラーを解決しよう
ブラウザで確認したところ、「We're sorry, but somethig went wrong.」のエラーが出てしまっている場合はlogファイルからエラーの原因を確認しましょう。
自動デプロイ後はcurrentディレクトリ
にログが格納されています。
1
[ec2-user@ip-172-12-34-5 レポジトリ名]$ tail -f current/log/production.log
こちらのコマンドでエラーがどこで起こっているか確認をしましょう。
自動デプロイツールを使うとこのように簡単にデプロイができるようになります。
コマンドの打ち間違いや作業のし忘れなどがなくなるメリットもあるので、ぜひ導入してみてはいかがでしょうか。他にもコードの品質を上げる方法などより現場レベルに近い知識を身につけたい方は、こちらの書籍で学ぶと深く理解することができます。
この記事のまとめ
- 自動デプロイツールとは面倒なデプロイ作業を簡単に行うことができるツール
- Capistranoは自動デプロイツールの一つ
- 導入するとコマンド1つでデプロイが完了