7839

雑草魂エンジニアブログ

【Rails】Capistrano で Rails アプリケーションを自動デプロイ(サーバー設定/デプロイ編)

先日の【Rails】Capistrano で Rails アプリケーションを自動デプロイ(設定編)に続き、今回は実際にデプロイするにあたり、サーバー側で事前に設定した内容に関して、備忘録として残しておく。

サーバーの環境構築に関しては、【EC2】Rails5 環境構築(Ruby + MySQL5.7 + Node.js + Nginx) を参照してほしい。

GitHubSSH 設定

EC2に特定の人の GitHub のアカウントを紐付けてもいいが、今回は GitHubリポジトリに公開鍵を登録することによって、SSH でアクセスできるようにする。

1. EC2 で公開鍵・秘密鍵を作成する(パスワードの設定もできるが、今回は設定せずに進めた。)

$ cd ~/.ssh
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again:

2. 公開鍵を authorized_keys に追加して、この鍵ペアを使用してログインできるようにする

$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

(※注意※)
「>>」で追加すること。「>」で上書きしてしまうと、EC2 に SSH 接続できなくなってしまうので、注意。

3. Clone したい GitHubリポジトリに対して、公開鍵を登録する

GitHubリポジトリのページにアクセスして、「Settings > Deploy keys」 に先ほど生成した id_rsa.pub を登録する。

4. git cloneできるか確認する

一度、適当なフォルダを作り、ID/PASSを入力せずに、cloneできるか確認する。

$ mkdir /home/ec2-user/tmp
$ cd /home/ec2-user/tmp
$ git clone git@github.com:<--Repository Name-->

問題なく、clone できれば設定完了である。(/home/ec2-user/tmp は不要なので、削除しておく。)

Capistrano でデプロイするディレクトリ作成

Capistranoディレクトリ構造を作成する際に、mkdir: permission denied のエラーが発生した。解決方法としては、様々な方法がある。

  1. デプロイ先のディレクトリを誰でも書き込めるようにする
  2. デプロイ先のディレクトリにec2-userが所属するグループを設定する
  3. デプロイ先のディレクトリの所有者を変更する
  4. Capistrano側で、sudo権限でディレクトリを作成できるようにする

1は簡単であるが、ちょっとセキュリティ的に嫌だったので、今回は「2」を実施することにした。

$ sudo mkdir /app
$ ls -ld
drwxrwxr-x 2 root root 6 1218 04:49 .
# /app の所有グループをwheelに変更する
$ sudo chgrp wheel /app
$ ls -ld
drwxrwxr-x 2 root wheel 6 1218 04:49 
# wheelグループに書き込み権限を付与する
$ sudo chmod g+w /app

共通ファイルのアップロード

現状の設定ファイルは以下のようになっている。(先日の記事から一部、抜粋している。)

~~省略~~
# 共有ファイル
append :linked_files, 'config/database.yml', 'config/master.key', 'config/credentials.yml.enc', 'config/puma.rb', '.env'
# 共有フォルダ
append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system', 'public/packs'

共有フォルダは自動で作成されるが、共有ファイルがないと、ファイル自体を参照することができないので、エラーが発生する。そのため、事前に config/database.yml, config/master.key, config/credentials.yml.enc, config/puma.rb, .env のファイルを作成する。

scp でのファイル転送、または直接サーバーへのファイル作成及び書き込みを行う。

$ scp [ローカルのファイルパス] [ユーザー名]@[サーバのIPアドレス]:[転送先のファイルパス]
$ scp database.yml ec2-user@test-staging:/app/sample-app/shared/config/database.yml

config/database.ymlは、それぞれの環境のDBのアクセス情報を記載しておく必要がある。config/puma.rbに関しては、次の章を参照してほしい。

Puma + Nginx の設定変更

アプリケーションのディレクトリが Capistranoディレクトリ構造に変わるので、参照するパスを変更する。(前回の設定は、
【Puma】Rails 5.2 + Puma + Nginx のデプロイ設定
を参照。)

# The directory to operate out of.
directory '/app/sample-app/current'
# Set the environment in which the rack's app will run. The value must be a string.
environment ENV.fetch("RAILS_ENV") { "production" }
# daemonize
daemonize false
# Store the pid of the server in the file at "path".
pidfile '/app/sample-app/current/tmp/pids/puma.pid'
# Use "path" as the file to store the server info state. This is used by "pumactl" to query and control the server.
state_path '/app/sample-app/current/tmp/pids/puma.state'
# Configure "min" to be the minimum number of threads to use to answer
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 16 }
threads threads_count, threads_count
# Bind the server to "url". "tcp://", "unix://" and "ssl://" are the only accepted protocols.
bind 'unix:///app/sample-app/shared/tmp/sockets/puma.sock'
on_restart do
# Code to run before doing a restart. This code should close log files, database connections, etc.
  ActiveRecord::Base.connection.disconnect! if defined?(ActiveRecord::Base)
end
# How many worker processes to run. 
workers 3
# Code to run in a worker before it starts serving requests.
on_worker_boot do
  ActiveSupport.on_load(:active_record) do
    ActiveRecord::Base.establish_connection
  end
end
# Preload the application before starting the workers
preload_app!
# Additional text to display in process listing
tag 'sample-app_puma'
# Verifies that all workers have checked in to the master process within the given timeout.
worker_timeout 60
# Change the default worker timeout for booting
worker_boot_timeout 60
# 各種ログのディレクトリ設定
access_log /app/sample-app/shared/log/nginx/nginx-access.log;
error_log /app/sample-app/shared/log/nginx/nginx-error.log;
# 処理を受け取る最大許容量
client_max_body_size 2G;

upstream app_server {
  server unix:///app/sample-app/shared/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name _;
  keepalive_timeout 5;
  # パスの変更
  root /app/sample-app/current/public;
  try_files $uri/index.html $uri.html $uri @app;
  location @app {
    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;
  location = /500.html {
    # パスの変更
    root /app/sample-app/current/public;
  }
}

ログファイルを作成しておく

$ sudo mkdir -p /app/sample-app/shared/log/nginx
$ sudo touch /app/sample-app/shared/log/nginx/nginx-access.log
$ sudo touch /app/sample-app/shared/log/nginx/nginx-error.log

設定ファイルに問題がないか確認を行う(successful が表示されれば、OK.)

$ sudo nginx -t
nginx: [warn] conflicting server name "_" on 0.0.0.0:80, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Nginxの設定を書き換えたので、再起動する

$ sudo systemctl reload nginx

デプロイ

これで、全ての準備が完了したので、いよいよデプロイである。

# staging環境の場合
$ bundle exec cap staging deploy
# production環境の場合
$ bundle exec cap production deploy

上記のコマンドだけで、それぞれのタスクが実行され、デプロイが完了する。本当にとても便利である。

デプロイしただけでは、設定が反映されなかった。Puma を再起動する必要があったので、注意が必要である。

まとめ

Capistrano で無事に Rails アプリケーションの自動デプロイを実施することができた。手作業で毎回、サーバーにSSH接続→git pull→build→…などをやる必要がなくなって、本当にとても楽である。

それでは、ステキな開発ライフを。

関連記事

serip39.hatenablog.com

serip39.hatenablog.com

serip39.hatenablog.com