2019年02月09日

RailsアプリをAWSでデプロイする②(各種設定編)

前回はRailsアプリを動かすために必要なソフトウェアのインストールを行いました。

今回はそれぞれの設定ファイルを記述しユーザーのリクエストに対し応答できるようにしましょう!

この記事の目次

  • 1.環境変数の設定ファイルを記述
  • 2.NginxとUnicornの設定ファイルを記述
  • 3.設定ファイルのディレクトリと内容一覧
  • 4.まとめ

環境変数の設定ファイルを記述

Railsの環境変数の設定

Railsの環境変数を設定します。

アプリのルートディレクトリ
$ bundle exec rake secret

このコマンドでシークレットキーを生成しSECRET_KEY_BASEに格納します。

ここではdotenv-railsを使った変数管理を使用しますが、echo $SECRET_KEY_BASEの結果が先ほど生成したシークレットキーと同じものになれば問題ないです。

Gemfile
# 環境変数の管理をするもの
gem 'dotenv-rails'
commandline
$ bundle install

アプリケーションのルートディレクトリに.envファイルを作成し記述します。

もし、サーバーからGithubへpushすることがあるなら.gitignoreに追記してから実行して下さい。

アプリのルートディレクトリ
$ touch .env
$ vim .env
.env
SECRET_KEY_BASE={secret-key}

記述の際に"で囲っても囲まなくても問題ないです。

ファイルの記述ができたら結果を確認しましょう。

アプリのルートディレクトリ
$ source .env
$ echo $SECRET_KEY_BASE

結果が返ってきたらきたら設定完了です。

MySQLの環境変数の設定

先ほどと同様にMySQLの変数を設定していきます。

.env
DB_NAME={database-name}
DB_USERNAME={user-name}
DB_PASSWORD={db-password}
DB_PORT="3306"
DB_HOSTNAME="localhost"

上の3つの変数を設定して下さい。

アプリのルートディレクトリ
$ source .env
$ echo $DB_NAME
$ echo $DB_USERNAME
$ echo $DB_PASSWORD
$ echo $DB_PORT
$ echo $DB_HOSTNAME

設定が反映されているかを確認します。

反映されていたらconfigファイルにも記述します。
socketの位置も記述します。

config/database.yml
production:
  <<: *default
  database: <%= ENV['DB_NAME'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock
  post: <%= ENV['DB_PORT'] %>
  host: <%= ENV['DB_HOSTNAME'] %>

NginxとUnicornの設定ファイルを記述

Nginxの設定ファイルを作成

etc/nginx/conf.dディレクトリに移動し、設定ファイルを作成し編集します。

/etc/nginx/conf.d
$ sudo touch {app-name}.conf
$ sudo vim {app-name}.conf
/etc/nginx/conf.d/{app-name}.conf
upstream unicorn_server {
    server unix:/var/run/.unicorn.sock
    fail_timeout=0;
}
server {
    listen 80;
    client_max_body_size 4G;
    server_name {IP-address};
    keepalive_timeout 5;
    # Location of our static files
    root /var/www/project/{app-name}/public;
    location ~ ^/assets/ {
        root /var/www/project/{app-name}/public;
    }
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        if (!-f $request_filename) {
            proxy_pass http://unicorn_server;
            break;
        }
    }
    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /var/www/project/{app-name}/public;
    }
} 

3箇所の{app-name}1箇所の{IP-address}を変更して下さい。

次に/etc/nginx/nginx.confを編集します。

/etc/nginx/nginx.conf
events { }
http {
  include mime.types;
  include /etc/nginx/conf.d/{app-name}.conf;
}

設定内容を消して先ほどのファイルを読み込む指定をします。

ファイルの権限を変更

次にNginxのlogファイルpidファイルの出力先の権限を変更します。
サーバーのルートディレクトリに移動します。

pwdのコマンド結果が「/」になるディレクトリであるか確認してからコマンドを実行して下さい。

/
$ pwd
/
$ sudo chown -R ec2-user var/lib/nginx var/log/nginx var/run/nginx.pid

権限を変更したらファイルの記述のシンタックステストを行なって下さい。

/
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

エラーが発生した場合は権限が正しいかを確認して下さい。

Unicornの設定ファイルを作成

アプリのルートディレクトリ
$ vim config/unicorn.rb
config/unicorn.rb
$worker  = 2
$timeout = 30
$listen  = "/var/run/unicorn.sock"
$pid     = "/var/run/unicorn.pid"
$std_log = "/var/run/unicorn.log"

RAILS_ROOT = File.expand_path('../../', __FILE__)
ENV['BUNDLE_GEMFILE'] = RAILS_ROOT + "/Gemfile"

worker_processes  $worker
stderr_path $std_log
stdout_path $std_log
timeout $timeout
listen  $listen
pid $pid
working_directory RAILS_ROOT
preload_app true


before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      Process.kill "QUIT", File.read(old_pid).to_i
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

設定をコーピーできたらファイルの記述は以上です。

設定ファイルのディレクトリと内容一覧

Railsの環境変数

/var/www/project/アプリ名/.env
SECRET_KEY_BASE={secret-key}
DB_NAME={database-name}
DB_USERNAME={user-name}
DB_PASSWORD={db-password}
DB_PORT="3306"
DB_HOSTNAME="localhost"

Railsのデータベースファイル

/var/www/project/アプリ名/config/database.yml
production:
  <<: *default
  database: <%= ENV['DB_NAME'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock
  post: <%= ENV['DB_PORT'] %>
  host: <%= ENV['DB_HOSTNAME'] %>

Nginxの設定ファイル

/etc/nginx/conf.d/{app-name}.conf
upstream unicorn_server {
    server unix:/var/run/.unicorn.sock
    fail_timeout=0;
}
server {
    listen 80;
    client_max_body_size 4G;
    server_name {IP-address};
    keepalive_timeout 5;
    # Location of our static files
    root /var/www/project/{app-name}/public;
    location ~ ^/assets/ {
        root /var/www/project/{app-name}/public;
    }
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        if (!-f $request_filename) {
            proxy_pass http://unicorn_server;
            break;
        }
    }
    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /var/www/project/{app-name}/public;
    }
} 
/etc/nginx/nginx.conf
events { }
http {
  include mime.types;
  include /etc/nginx/conf.d/{app-name}.conf;
}

Unicornのインストール

Gemfile
group :production do
  gem 'unicorn'
end
アプリのルートディレクトリ
$ bundle install

Unicornの設定ファイル

config/unicorn.rb
$worker  = 2
$timeout = 30
$listen  = "/var/run/unicorn.sock"
$pid     = "/var/run/unicorn.pid"
$std_log = "/var/run/unicorn.log"

RAILS_ROOT = File.expand_path('../../', __FILE__)
ENV['BUNDLE_GEMFILE'] = RAILS_ROOT + "/Gemfile"

worker_processes  $worker
stderr_path $std_log
stdout_path $std_log
timeout $timeout
listen  $listen
pid $pid
working_directory RAILS_ROOT
preload_app true


before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      Process.kill "QUIT", File.read(old_pid).to_i
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

まとめ

今回は設定ファイルについてでした。
デプロイ時のエラーは設定ファイルの記述とファイルやディレクトリの権限によるものがほとんどです。
着実に進めていきましょう。
ありがとうございました!