capistrano3を使ってRailsアプリをさくらVPSにデプロイする

前回の記事の続き。 capistrano3を使って、VPS上にRailsアプリをデプロイする。

↓の記事を参考にした。 Rails5+Puma+Nginxな環境をCapistrano3でEC2にデプロイする(前編)

1. Gemの追加

デプロイに使うGemを設定する。 Gemfileに下記追加。

# Use Puma as the app server
gem 'puma', '~> 3.7'

group :development do
  gem 'capistrano', '3.7.0'
  gem 'capistrano-rails'
  gem 'capistrano-bundler'
  gem 'capistrano-rbenv'
  gem 'capistrano-rbenv-vars'
end
$ bundle install

2. capistranoの設定を追加

下記コマンドを実行することで、設定ファイルが自動で作成される。

$ 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

まず、Capfileを以下のように編集。

require "capistrano/setup"
require "capistrano/deploy"
require "capistrano/scm/git"

install_plugin Capistrano::SCM::Git

Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

次に、config/deploy.rbを編集。

lock "3.7.0"

set :application, "アプリ名"
set :repo_url, "git@github.com:ユーザー名/アプリ名.git"

namespace :deploy do
  desc "Make sure local git is in sync with remote."
  task :confirm do
    on roles(:app) do
      puts "This stage is '#{fetch(:stage)}'. Deploying branch is '#{fetch(:branch)}'."
      puts 'Are you sure? [y/n]'
      ask :answer, 'n'
      if fetch(:answer) != 'y'
        puts 'deploy stopped'
        exit
      end
    end
  end

  desc 'Initial Deploy'
  task :initial do
    on roles(:app) do
      invoke 'deploy'
    end
  end

  before :starting, :confirm
end

最後に、config/deploy/production.rbを編集。

server "IPアドレス", user: "deploy", roles: %w{app db web}

set :ssh_options, {
  keys: %w(~/.ssh/id_rsa),
  forward_agent: true,
  auth_methods: %w(publickey)
}

2. デプロイ用ユーザーの作成

$ sudo su -
$ useradd deploy
$ passwd deploy
$ sudo visudo

## Allow root to run any commands anywhere
root   ALL=(ALL) ALL
deploy ALL=(ALL) ALL ← この1行を追加

SSH接続のための鍵の設定をする。

$ su - deploy
=> 先程作成したdeployユーザーに切り替え
$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
$ vi ~/.ssh/authorized_keys
=> ローカルで作成した公開鍵を貼り付ける
$ chmod 600 ~/.ssh/authorized_keys

3. アプリケーションのデプロイ先のディレクトリを作成

$ pwd
/home/deploy

$ sudo mkdir /var/www && cd /var/www
$ sudo mkdir アプリ名
$ sudo chown deploy:deploy アプリ名

4. GitHubの設定

サーバーからGitHubに接続するために、公開鍵を登録する。

$ ssh-keygen -t rsa -v
=> まずは公開鍵と秘密鍵のペアを作成

作成した公開鍵を下記のページからGitHubに登録。

https://github.com/settings/ssh/new

SSHで接続確認。

$ ssh -T git@github.com
Hi ユーザー名! You've successfully authenticated, but GitHub does not provide shell access.
=> このメッセージが表示されればOK.

5. 試しデプロイ実行

ここまで出来たら、一旦デプロイを実行してみる。

$ bundle exec cap production deploy
=> deploy:log_revision まで実行出来たらOK

6. 必要なパッケージのインストール

yum で必要なパッケージをインストールする。

$ pwd
/home/deploy

$ sudo yum update
$ sudo yum install git
$ sudo yum install gcc
$ sudo yum install gcc-c++
$ sudo yum install openssl-devel
$ sudo yum install readline-devel
$ sudo yum install mysql-devel
$ sudo yum -y install nodejs

ruby-build のインストール

$ git clone git://github.com/sstephenson/ruby-build.git
$ sudo ruby-build/install.sh

rbenv のインストール

$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
$ exec $SHELL -l

$ rbenv --version
rbenv 1.1.1

rbenv-varsのインストール

$ git clone https://github.com/rbenv/rbenv-vars.git $(rbenv root)/plugins/rbenv-vars

ruby2.4.1のインストール

$ rbenv install 2.4.1
$ rbenv global 2.4.1
$ rbenv rehash

$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]

bundler のインストール

$ gem install bundler

rubyracer のインストール

$ gem install therubyracer

Rails 5.1.6 のインストール

$ gem install rails -v 5.1.6

$ rails -v
Rails 5.1.6

puma のインストール

$ gem install puma

MySQL をインストール

参考記事:MySQL8をCentOS7にインスール(開発環境用)

$ rpm -qa | grep maria
mariadb-libs-5.5.60-1.el7_5.x86_64
=> mariadb が入っていないか確認
$ sudo yum remove mariadb-libs
=> mariadbのパッケージをアンインストール
$ sudo yum -y localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
$ sudo yum -y install mysql mysql-devel mysql-server mysql-utilities
$ sudo systemctl start mysqld

7. nginxの設定を修正

/etc/nginx/nginx.conf を下記のように編集する。

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    index   index.html index.htm;

    upstream puma {
        server unix:///var/www/アプリ名/shared/tmp/sockets/puma.sock;
    }
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  localhost;
        root         /var/www/アプリ名/current/public;

        include /etc/nginx/default.d/*.conf;

        location / {
            try_files $uri $uri/index.html $uri.html @webapp;
        }

        location @webapp {
            proxy_read_timeout 300;
            proxy_connect_timeout 300;
            proxy_redirect off;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://puma;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

8. デプロイ設定の修正

本番環境で、下記のディレクトリが /var/www/アプリ名/shared/ の下に配置されるように設定を編集する。

ローカルに戻り以下の設定を編集する。

config/puma.rbに下記追加。

app_dir = File.expand_path("../..", __FILE__)
bind "unix://#{app_dir}/tmp/sockets/puma.sock"
pidfile "#{app_dir}/tmp/pids/puma.pid"
state_path "#{app_dir}/tmp/pids/puma.state"
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true

config/deploy.rb に下記追加

append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"

デプロイを実行

$ bundle exec cap production deploy

9. SECRET_KEY_BASE の設定

以下のコマンドで本番環境の SECRET_KEY_BASE を環境変数に設定する。

$ export SECRET_KEY_BASE=`bundle exec rake secret`

10. MySQL の初期設定

Rootユーザーの初期パスワードを変更する。

参考:(MySQL8をCentOS7にインスール(開発環境用))https://d-ebi.hatenablog.com/entry/2018/11/26/210000

$ sudo grep 'temporary password' /var/log/mysqld.log
2018-11-26T01:55:34.881029Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: Rw.gaqQMp2>R
=> 初期パスワードを確認する
$ mysql_secure_installation
Enter password for user root:
=> 初期パスワードを入力して、パスワード設定などを行う。

アプリケーションで使用する(config/database.ymlに記載されている)本番用のDBとユーザーの作成。

$ mysql -u root -p
mysql> create database DB名;
Query OK, 1 row affected (0.10 sec)
mysql> create user ユーザー名@localhost identified by パスワード;
Query OK, 0 rows affected (0.01 sec)
mysql> grant all on DB名.* to ユーザー名@localhost; 
Query OK, 0 rows affected (0.03 sec)

11. MySQLのSocketファイルの設定

MySQLのSocketファイルの出力先パスを調べて config/database.yml に設定する。

$ mysqladmin -u root version -p
..
UNIX socket     /var/lib/mysql/mysql.sock
...
=> このパスを `config/database.yml` に追記する。

12. asset compile

$ bundle exec rake assets:precompile RAILS_ENV=production

12. Pumaの再起動

サーバーに接続して、Pumaを再起動する。

$ cd /var/www/アプリ名/current
$ bundle exec puma -t 5:5 -e production -C config/puma.rb
=> Pumaを起動

起動に成功すれば、socketファイルやpidファイルが生成される。