Rails4+Capistrano3+Nginx+Unicorn EC2へのデプロイ < 前編 >

  • 1
    いいね
  • 0
    コメント

インフラ勉強中の者がAWSにrailsアプリをEC2にデプロイしたので備忘録として残します。
長いので<前編><後編>の2回に分けて実施致します。

【前提】
・今回はscaffoldで作成した簡単なアプリ(userの名前と年齢を登録するアプリ)をデプロイすることをゴールに進めていきます。
・デプロイのディレクトリは /var/www/qiitaAppです。
shared/config 配下のdatabase.ymlsecrets.yml は手動で作成します。
・ローカルへのRubyやRailsのインストールとEC2、RDSのセットアップ(VPCやセキュリティグループ等々の設定)、GitHubのアカウント登録に関しての説明は致しません。
・hostの設定、各環境毎の設定は実施しません。

Rubyのインストール
Ruby on Railsのインストールと設定
AWSの設定

【イメージ】
スクリーンショット 2017-05-09 11.04.30.png

【バージョン】

software version
Ruby 2.3.3
Rails 4.2.7
Nginx 1.10.2
Unicorn 5.3.0
MySql 5.6
Capistrano 3.8.1
capistrano3-unicorn 0.2.1

今回は、デプロイ時にUnicornの再起動もさせるべくcapistrano3-unicornというgemを使用します。
(自身でtaskとして設定する事も可能です。)

GitHubの設定

1)New Repositoryの生成
Repository name → qiitaApp
Public
Create repository

2)ローカルからSSH接続ができるように[SSH keys]を追加する
今回は説明は省略します。
(EC2からもGitHub接続が必要なのでそちらは下記に記載します。)
GitHub 初心者による GitHub 入門(1)

EC2(AmazonLinux)の設定

1) git,rbenvのインストール

[myname@ip-10-0-1-86 ~]$ sudo yum -y install git
[myname@ip-10-0-1-86 ~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv #rbenvインストール
[myname@ip-10-0-1-86 ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build #ruby-buildインストール
[myname@ip-10-0-1-86 ~]$ sudo vi .bash_profile #.bash_profileの編集

=ファイルの編集画面=

export PATH
export PATH="$HOME/.rbenv/bin:$PATH" ← 追加
eval "$(rbenv init -)" ← 追加

=================

[myname@ip-10-0-1-86 ~]$ source ~/.bash_profile #環境変数の反映
[myname@ip-10-0-1-86 ~]$ rbenv -v #バージョン確認
rbenv 1.1.0-2-g4f8925a

2) Ruby2.3.3のインストール

[myname@ip-10-0-1-86 ~]$ sudo yum install -y gcc
[myname@ip-10-0-1-86 ~]$ sudo yum install -y openssl-devel readline-devel zlib-devel
[myname@ip-10-0-1-86 ~]$ rbenv install 2.3.3

3) Nginxのインストール・設定

[myname@ip-10-0-1-86 ~]$ sudo yum install nginx
[myname@ip-10-0-1-86 ~]$ cd /etc/nginx/conf.d/
[myname@ip-10-0-1-86 conf.d]$ sudo touch local.conf
[myname@ip-10-0-1-86 conf.d]$ sudo vi local.conf

==================== local.conf ===================================

upstream unicorn {
  server unix:/tmp/unicorn.sock;
}

server {
  listen 80;
  server_name YOUR_IP_ADDRESS;

  access_log /var/log/nginx/sample_access.log;
  error_log /var/log/nginx/sample_error.log;

  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass http://unicorn;
  }
}

=================================================================

4) デプロイするディレクトリと権限の変更

[myname@ip-10-0-1-86 conf.d]$ cd /var/
[myname@ip-10-0-1-86 var]$ sudo mkdir www
[myname@ip-10-0-1-86 var]$ sudo chmod 777 www
[myname@ip-10-0-1-86 var]$ cd www
[myname@ip-10-0-1-86 www]$ mkdir qiitaApp
[myname@ip-10-0-1-86 www]$ cd qiitaApp
[myname@ip-10-0-1-86 qiitaApp]$ rbenv local 2.3.3

5) GitHubへの接続 SSHkey

[myname@ip-10-0-1-86 qiitaApp]$ cd 
[myname@ip-10-0-1-86 ~]$ ssh-keygen -t rsa
$ cat .ssh/id_rsa.pub
ssh-rsa abcdefghijklmnopqrstuvwxyz1234567890 ec2-user@ip-10-0-1-86

[ssh-rsa]から[ec2-user@ip-10-0-1-86]までをコピーしてGitHubのSSH keysにNewKeyとして追加する

5) その他必要なソフトウェアのインストール・設定

  • bundler
[myname@ip-10-0-1-86 ~]$ rbenv exec gem install bundler
[myname@ip-10-0-1-86 ~]$ rbenv rehash
  • Node.js
[myname@ip-10-0-1-86 ~]$ sudo yum install nodejs --enablerepo=epel
  • sqlite
[myname@ip-10-0-1-86 ~]$ sudo yum install sqlite-devel
  • mysql
[myname@ip-10-0-1-86 ~]$ sudo yum install mysql-devel

ローカルの設定

1) railsアプリの生成とgemのインストール

$ rails new qiitaApp
$ cd qiitaApp/
$ git init
$ vi Gemfile

============ Gemfile ===============

gem 'unicorn' #コメントアウトを解除する
gem 'mysql2'                                                                                                                                                                                                       
group :development do
  gem 'capistrano'
  gem 'capistrano-rails'
  gem 'capistrano-bundler'
  gem 'capistrano-rbenv'
  gem 'capistrano3-unicorn'
end

===================================

$ bundle install
$ rails g scaffold user name:string age:integer
$ rake db:migrate

2) Capistranoの設定に必要なファイルの生成

$ bundle exec cap install STAGES=production #自動で下記のディレクトリとファイルを生成
mkdir -p config/deploy
create config/deploy.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
create Capfile
Capified

3) Capfileの設定

$ vi Capfile #下記を追加
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'

4) config/deploy.rbの設定

$ vi config/deploy.rb

lock "3.8.1"

set :application, "qiitaApp"
set :repo_url, "git@github.com:YOUR_GITHUB_ACCOUNT/qiitaApp.git"

set :rbenv_type, :user
set :rbenv_ruby, '2.3.3'
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
set :rbenv_roles, :all

set :log_level, :warn 

# Default value for :linked_files is []
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')

# Default value for linked_dirs is []
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')

# Default value for keep_releases is 5
set :keep_releases, 3

set :unicorn_pid, "#{shared_path}/tmp/pids/unicorn.pid"

set :unicorn_config_path, -> { File.join(current_path, "config", "unicorn.rb") }

namespace :deploy do
  after :restart, :clear_cache do
    on roles(:web), in: :groups, limit: 3, wait: 10 do
      # Here we can do anything such as:
      # within release_path do
      #   execute :rake, 'cache:clear'
      # end
    end
  end
end

after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end    

5) config/deploy/production.rbの設定

set :branch, 'master'

server 'EC2-IP-ADDRESS', user: 'ec2-user', roles: %w{app db web} ※

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

※今回はEC2-userでログインする設定で進めていきます。
本来はデプロイユーザを設定して、そのユーザのみがデプロイ可能にすべきだと思います。

7) Unicornの設定

手動で config 配下に unicorn.rb を生成

$ cd config
$ touch unicorn.rb
$ vi unicorn.rb

========================== unicorn ==============================

APP_PATH   = "#{File.dirname(__FILE__)}/.." unless defined?(APP_PATH)
RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
RAILS_ENV  = ENV['RAILS_ENV'] || 'development'

worker_processes 3

listen "/tmp/unicorn.sock"
pid "tmp/pids/unicorn.pid"

preload_app true

timeout 60
working_directory APP_PATH

# log
stderr_path "#{RAILS_ROOT}/log/unicorn_error.log"
stdout_path "#{RAILS_ROOT}/log/unicorn_access.log"

if GC.respond_to?(:copy_on_write_friendly=)
  GC.copy_on_write_friendly = true
end

before_exec do |server|
  ENV['BUNDLE_GEMFILE'] = APP_PATH + "/Gemfile"
end

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

  old_pid = "#{ server.config[:pid] }.oldbin"
  unless 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

=================================================================

ここまでで各種設定に関しては終了です。
shared/config 配下のdatabase.ymlsecrets.yml は手動で作成します。
が残っていますが、こちらは後編で実施します。

最後にGitHubにここまでのコードをあげておきます。

$ git add .
$ git commit -m "first commint(任意)"
$ git remote add origin git@github.com:YOUR_GITHUB_ACCOUNT/qiitaApp.git
$ ssh-add ~/.ssh/id_rsa_github
$ git push origin master

前編は以上です。
後編ではデプロイチェック、デプロイ、ログ確認を実施します。