DesignAssembler

備忘録に近い

ChefでAWSにRails+nginx+unicornのサーバーを立てる

環境構築の続きです

hyottokoaloha.hatenablog.com

hyottokoaloha.hatenablog.com

hyottokoaloha.hatenablog.com

hyottokoaloha.hatenablog.com

やること

chefで、railsをnginx+unicornの環境構築をします。

railsunicornのインストール

cookbooks/ruby_on_rails/recipes/default.rbを新規作成してください。

#cookbooks/ruby_on_rails/recipes/default.rb
['libxml2', 'libxslt', 'libxml2-devel', 'libxslt-devel', 'ruby-devel'].each do |pkg|
  package pkg do
    action :install
  end
end

bash "install rails" do
  code <<-EOC
    gem install json_pure
    gem install nokogiri -- --use-system-libraries
    export PATH="#{node['home_path']}/.rbenv/bin:$PATH"
    eval "$(rbenv init -)"
    gem update --system
    gem install --no-ri --no-rdoc rails
  EOC
end

次にcookbooks/unicorn/recipes/default.rbを新規作成してください。

bash "install unicorn" do
  code <<-EOC
    gem install unicorn
  EOC
end

そしてVagrantfileに以下を追記します

      "recipe[ruby_on_rails]",
      "recipe[unicorn]",

追記するとこうなります

  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = "./cookbooks"
    chef.run_list = [
      "recipe[nginx]",
      "recipe[ruby_build]",
      "recipe[ruby_rbenv::system]",
      "recipe[mysql_pkg]",
      "recipe[ruby_on_rails]",
      "recipe[unicorn]",
    ]
    chef.json = {
      rbenv: {
        rubies: ["2.2.2"],
        global: "2.2.2"
      }
    }
  end

MySQLにユーザー、データベースを作成

mysqlの起動でエラーが出ました

Can't connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock' (2)

mysql.sockがないということなので以下のように対応しました cookbooks/mysql_create/recipes/default.rbを新規作成

#cookbooks/mysql_create/recipes/default.rb
bash 'touch mysql.sock' do
  code <<-EOC
    touch /var/lib/mysql/mysql.sock
    chown mysql:mysql /var/lib/mysql/mysql.sock
  EOC
end

ユーザー、データベースの作成は以下の記事を参照

hyottokoaloha.hatenablog.com

ユーザー名とグループ名はec2-userに変更します。

node.default['mysql']['develop_user'] = 'dev_user'
node.default['mysql']['develop_password'] = 'develop_password'
node.default['mysql']['develop_db_name'] = 'development'
node.default['mysql']['user'] = 'ec2-user'
node.default['mysql']['group'] = 'ec2-user'

railsアプリケーションの作成

今回はお試しなので適当なrailsアプリケーションのリポジトリ作ってそこからアプリケーションをダウンロードします。

$ rails new test_app
$ rails g scaffold user name:string

mysqlの設定

config/database.ymlを編集します

#config/database.yml
development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: development
  pool: 5
  username: dev_user
  password: develop_password

mysql2でエラーが出るのでバージョン指定で解決。

#Gemfile
gem 'mysql2', '~> 0.3.18'

ruby on rails - Gem::LoadError for mysql2 gem, but it's already in Gemfile - Stack Overflow

んで、githubに投げます。

https://github.com/asmsuechan/rails_app

そしてセットアップ用のクックブックを作ります。 cookbooks/setup/recipes/default.rbを新規作成します。

#cookbooks/setup/recipes/default.rb
['mysql-devel','sqlite-devel'].each do |pkg|
  package pkg do
    action :install
  end
end

bash "setup application" do
  code <<-EOC
    git clone https://github.com/asmsuechan/rails_app.git /home/ec2-user/rails_app
    cd /home/ec2-user/rails_app;bundle install;rake db:migrate
    chown -R ec2-user:ec2-user /home/ec2-user/rails_app
  EOC
end

これでrails sしたら通りました。

nginx+unicornの設定

設定に関してはここを丸々参考にさせてもらいました。

http://qiita.com/Salinger/items/5350b23f8b4e0dcdbe23

cookbooks/setup/recipes/default.rbに以下を追記

#cookbooks/setup/recipes/default.rb

bash "setup application" do
  code <<-EOC
    git clone https://github.com/asmsuechan/rails_app.git /home/ec2-user/rails_app
    cd /home/ec2-user/rails_app;bundle install;rake db:migrate
    chown -R ec2-user:ec2-user /home/ec2-user/rails_app
  EOC
end

template 'unicorn.rb' do
  path '/home/ec2-user/rails_app/config/unicorn.rb'
  source 'unicorn.rb.erb'
  owner 'ec2-user'
  group 'ec2-user'
end

bash 'up unicorn' do
  code <<-EOC
    chown -R #{node.default['user']}:#{node.default['user']} #{node.default['root_dir']}
    cd /home/ec2-user/rails_app;bundle exec unicorn_rails -c config/unicorn.rb -E development -D
  EOC
end

bash 'rm nginx.conf' do
  code <<-EOC
    rm /etc/nginx/nginx.conf
  EOC
end

template 'nginx.conf' do
  path '/etc/nginx/nginx.conf'
  source 'nginx.conf.erb'
  owner 'root'
  group 'root'
  mode '644'
end

template 'conf.d/myapp.conf' do
  path '/etc/nginx/conf.d/myapp.conf'
  source 'myapp.conf.erb'
  owner 'root'
  group 'root'
  mode '644'
end

テンプレートファイルの作成

nginx

#cookbooks/setup/templates/nginx.conf.erb
upstream unicorn {
  server unix:<%= node.default['root_dir']%>/tmp/unicorn.sock;
}

server {
  listen 80 default_server;
  server_name localhost;

  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;

  root <%= node.default['root_dir'] %>;

  client_max_body_size 100m;
  error_page 404 /404.html;
  error_page 500 502 503 504 /500.html;
  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    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;
  }
}

unicorn

worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true  # 更新時ダウンタイム無し

listen "<%= node.default['root_dir'] %>/tmp/unicorn.sock"
pid "<%= node.default['root_dir'] %>/tmp/unicorn.pid"

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

# ログの出力
stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])

変数の設定です

#cookbooks/setup/attributes/default.rb
node.default['root_dir'] = '/home/ec2-user/rails_app'
node.default['user'] = 'ec2-user'
node.default['group'] = 'ec2-user'

最後に、ブラウザからアクセスして確認できたら完了です

f:id:hyottokoaloha:20160215103802p:plain

f:id:hyottokoaloha:20160215103827p:plain

出たエラー

いろんなエラーにハマりました。

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (13)

d.hatena.ne.jp

qiita.com

/etc/nginx/nginx.confのuserをec2-userにしました。

2016/02/14 13:07:26 [crit] 31209#0: *16 connect() to unix:/home/ec2-user/rails_app/tmp/unicorn.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://unix:/home/ec2-user/rails_app/tmp/unicorn.sock:/500.html", host: "localhost"

【nginx/unicorn】(13: Permission denied) while connecting to upstream | COTeggのバケツ

参考

mashi.hatenablog.com

【nginx/unicorn】(13: Permission denied) while connecting to upstream | COTeggのバケツ