ChefでAWSにRails+nginx+unicornのサーバーを立てる
環境構築の続きです
やること
chefで、railsをnginx+unicornの環境構築をします。
rails、unicornのインストール
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
ユーザー、データベースの作成は以下の記事を参照
ユーザー名とグループ名は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; } }
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'
最後に、ブラウザからアクセスして確認できたら完了です
出たエラー
いろんなエラーにハマりました。
- mysqlに繋げない
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (13)
/etc/nginx/nginx.confのuserをec2-userにしました。
- unicorn.sockに繋げない
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のバケツ
参考
【nginx/unicorn】(13: Permission denied) while connecting to upstream | COTeggのバケツ