1:デプロイの自動化
数ある自動デプロイツールの中でも、もっともポピュラーなCapistranoを導入して、デプロイを自動化する。
2:自動デプロイツールのメリット
自動デプロイツールを利用することによって、デプロイ時に必要なコマンド操作が1回で済むようになります。これにより、手動デプロイする場合に起こりがちな下記の問題を解消できます。
手動デプロイで起こりがちな問題
・コマンドの打ち間違い、手順の間違いが発生する可能性がある
・手順が多く、煩わしい
3:Capistranoの導入準備
まずは、Capistranoを利用するためのGemをインストールします。
①Gemfileを以下のように編集します。
「group :development, :test do ~ end」がすでに記述されている場合は、「gem ~」の部分だけを追記します。
Gemfile
group :development, :test do
gem 'capistrano'
gem 'capistrano-rbenv'
gem 'capistrano-bundler'
gem 'capistrano-rails'
gem 'capistrano3-unicorn'
end
②ターミナル(ローカル):アプリケーションのディレクトリで実行します。
% bundle install
⇩
gemを読み込めたら、下記のコマンドを打ちます。
③ターミナル(ローカル):アプリケーションのディレクトリで実行します。
% bundle exec cap install
4:Capfileを下記のように編集します。Capfile→Gemfileの2つ上にあるファイル。
require "capistrano/setup"
require "capistrano/deploy"
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
5:production.rbの一番下に、下記のように編集します。
config/deploy/production.rb
server '用意したElastic IP', user: 'ec2-user', roles: %w{app db web}
↓
例:server '11.366.64.450', user: 'ec2-user', roles: %w{app db web}
6:deploy.rbを下記のように編集します。
config/deploy.rb
capistranoのバージョンを記載。固定のバージョンを利用し続け、バージョン変更によるトラブルを防止する
lock 'Capistranoのバージョン'
Capistranoのログの表示に利用する
set :application, 'ご自身のアプリケーション名'
どのリポジトリからアプリをpullするかを指定する
set :repo_url, 'git@github.com:Githubのユーザー名/レポジトリ名.git'
バージョンが変わっても共通で参照するディレクトリを指定
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')
set :rbenv_type, :user
set :rbenv_ruby, 'このアプリで使用しているrubyのバージョン' #カリキュラム通りに進めた場合、’2.6.5’ です
どの公開鍵を利用してデプロイするか
set :ssh_options, auth_methods: ['publickey'],
keys: ['~/.ssh/ご自身のキーペア名.pem']
プロセス番号を記載したファイルの場所
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }
Unicornの設定ファイルの場所
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5
デプロイ処理が終わった後、Unicornを再起動するための記述
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:restart'
end
end
※「Capistranoのバージョン」は、Gemfile.lockに記載されています。以下のように書かれている場合は「3.8.0」です。
【例】Gemfile.lock
capistrano (3.8.0)
7:Unicornの設定ファイルを下記のように編集します。
config/unicorn.rb
#サーバ上でのアプリケーションコードが設置されているディレクトリを変数に入れておく
app_path = File.expand_path('../../../', FILE) # 「../」が一つ増えている
#アプリケーションサーバの性能を決定する
worker_processes 1
#アプリケーションの設置されているディレクトリを指定
working_directory "#{app_path}/current" # 「current」を指定
#Unicornの起動に必要なファイルの設置場所を指定
pid "#{app_path}/shared/tmp/pids/unicorn.pid" # 「shared」の中を参照するよう変更
#ポート番号を指定
listen "#{app_path}/shared/tmp/sockets/unicorn.sock" # 「shared」の中を参照するよう変更
#エラーのログを記録するファイルを指定
stderr_path "#{app_path}/shared/log/unicorn.stderr.log" # 「shared」の中を参照するよう変更
#通常のログを記録するファイルを指定
stdout_path "#{app_path}/shared/log/unicorn.stdout.log" # 「shared」の中を参照するよう変更
8:Nginxの設定ファイルを編集します。
ターミナル(EC2内で実行)
$ sudo vim /etc/nginx/conf.d/rails.conf
9:/etc/nginx/conf.d/rails.conf
upstream app_server {
Unicornと連携させるための設定
server unix:/var/www/リポジトリ名/shared/tmp/sockets/unicorn.sock;
}
{}で囲った部分をブロックと呼ぶ。サーバの設定ができる
server {
このプログラムが接続を受け付けるポート番号
listen 80;
接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない
server_name Elastic IP;
クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく
client_max_body_size 2g;
接続が来た際のrootディレクトリ
root /var/www/リポジトリ名/current/public;
assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
root /var/www/リポジトリ名/current/public;
}
try_files $uri/index.html $uri @unicorn;
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://app_server;
}
error_page 500 502 503 504 /500.html;
}
⇨入力を終えたら「escキー」→「:wq」の順で実行し、保存します。
そして、Nginxの設定を変更したら、忘れずに再読込・再起動をします。
ターミナル(EC2内で実行)
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl reload nginx
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl restart nginx
9:データベースの起動を確認します。
データベースが立ち上がっていないとデプロイが失敗します。以下のコマンドでデータベースの状態を確認しておきます。
ターミナル(EC2内で実行)
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl status mariadb
※以下のように、「active」と表示されれば起動しています。
ターミナル(EC2)
● mariadb.service - MariaDB database server
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled)
Active: active (running) since 金 2020-07-17 03:46:51 UTC; 8s ago
→万が一、「active」になっていない場合はsudo systemctl start mariadbを実行します。
11:続いて、プロセスをkillします。
ターミナル(EC2内で実行)
上記の例だと「17877」
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill プロセス番号
12:ローカルでの修正をすべてmasterにpushします。
ローカルでのコードの変更が、すべてmainブランチにpushされていることを確認しておきます。
以上で自動デプロイの準備は完了です。
13:自動デプロイを実行しましょう
ローカルのターミナルに戻り、以下のコマンドで自動デプロイを実行します。
ターミナル(ローカル):アプリケーションのディレクトリで実行します。
% bundle exec cap production deploy
※はじめての自動デプロイでは「bundler install」のタスクで時間がかかることがあります。5分経っても動かない場合は「EC2インスタンスの再起動」を実行します。
EC2インスタンスの再起動後は、必ず「データベース」「Nginx」の再起動も行います。
ターミナル(EC2内で実行)
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl restart mariadb
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl restart nginx
14:エラーの例
①Bundler::GemNotFound: Could not find date-3.3.3 in any of the sourcesについて、外部サイトで検索すると
エラーの原因
2022/12/3にrailsの必須gemの一つであるmailが2.7.1から2.8にアップデートされたことで、
このgemバージョンで使用するdateというgemが、EC2側で取得できておらずエラーが発生しているとのことです。
そして、解決方法について、
①Gemfileの末尾に「gem 'mail', '2.7.1'」を追記。(mailのバージョンを下げる指定をすることで、dateのgemを取得しないようにする為。)
*Gemfileに「gem 'date', '~> 3.3', '>= 3.3.3'」を記述した場合は、gem 'date'の記述を削除。
②Gemfile.lockの削除方法
↓
VSコードから「Gemfile.lock」をファイルごと削除すれば大丈夫。
理由:
Gemfile.lockはbundle installを実行すると生成される履歴ファイルであるため、削除を行ってからbundle installしないとpgをインストールした過去の履歴が残ってしまい、エラーが解消されない可能性があります。
■pgのgemを完全に削除する手順
1:Gemfileで、「gem 'pg'」の記述を削除する
2:VScodeからGemfile.lockを右クリックで削除、ローカル環境のfurimaアプリでbundle installをおこなう
3:GitHubにコミットとプッシュ
4:EC2環境でgit pull origin master(※デフォルトブランチがmainの場合はgit pull origin main)
5:EC2環境内のアプリケーションでbundle install
③ローカルでbundle install
④コミットプッシュ
⑤EC2内で自動デプロイ実行(% bundle exec cap production deploy)