【Rails】Capistrano で Rails アプリケーションを自動デプロイ(サーバー設定/デプロイ編)
先日の【Rails】Capistrano で Rails アプリケーションを自動デプロイ(設定編)に続き、今回は実際にデプロイするにあたり、サーバー側で事前に設定した内容に関して、備忘録として残しておく。
- Capistrano ver.3.14.1
- Rails ver.5.2.4
- AmazonLinux2
サーバーの環境構築に関しては、【EC2】Rails5 環境構築(Ruby + MySQL5.7 + Node.js + Nginx) を参照してほしい。
GitHub の SSH 設定
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
のエラーが発生した。解決方法としては、様々な方法がある。
- デプロイ先のディレクトリを誰でも書き込めるようにする
- デプロイ先のディレクトリにec2-userが所属するグループを設定する
- デプロイ先のディレクトリの所有者を変更する
- Capistrano側で、sudo権限でディレクトリを作成できるようにする
1は簡単であるが、ちょっとセキュリティ的に嫌だったので、今回は「2」を実施することにした。
$ sudo mkdir /app $ ls -ld drwxrwxr-x 2 root root 6 12月 18 04:49 . # /app の所有グループをwheelに変更する $ sudo chgrp wheel /app $ ls -ld drwxrwxr-x 2 root wheel 6 12月 18 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→…などをやる必要がなくなって、本当にとても楽である。
それでは、ステキな開発ライフを。