Ruby on Rails Unicorn Nginx で環境構築
Overview
Ruby on Railsをnginx で動作させたく、Unicornを使ってやってみました。
Nginxをリバースプロキシにして、Unicornで受けて、Ruby on Railsというフローから、
Ruby on Rails -> Unicorn -> Nginx というフロー的な感じです。
Ruby version: 2.3.3
Rails version: 5.0.6
nginx version: 1.12.2
mysql version: 5.1.7
Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "bento/centos-6.9"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
config.vm.network "forwarded_port", guest: 80, host: 1234
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network "private_network", ip: "192.168.33.10"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
config.vm.synced_folder "./html", "/usr/share/nginx/html"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
#
# View the documentation for the provider you are using for more
# information on available options.
# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision "shell", inline: <<-SHELL
# apt-get update
# apt-get install -y apache2
# SHELL
end
Nginx conf
upstream unicorn_server {
# This is the socket we configured in unicorn.rb
server unix:/tmp/unicorn.sock
fail_timeout=0;
}
server {
listen 80;
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
# Location of our static files
root /usr/share/nginx/html;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
# If you don't find the filename in the static files
# Then request it from the unicorn server
if (!-f $request_filename) {
proxy_pass http://unicorn_server;
break;
}
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /usr/share/nginx/html;
}
}
->> sudo service nginx restart
Stopping nginx: [ OK ]
Starting nginx: [ OK ]
Gemfile 編集
source 'https://rubygems.org'
git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
"https://github.com/#{repo_name}.git"
end
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.6'
# Use mysql as the database for Active Record
gem 'mysql2', '>= 0.3.18', '< 0.5'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# See https://github.com/rails/execjs#readme for more supported runtimes
gem 'therubyracer', platforms: :ruby
# Use unicorn as the app server
gem 'unicorn'
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platform: :mri
end
group :development do
# Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '~> 3.0.5'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
bundle install --path vendor/bundle
Rails project unicorn.rb
@app_path = '/usr/share/nginx/html'
worker_processes 2
working_directory "#{@app_path}/"
# This loads the application in the master process before forking
# worker processes
# Read more about it here:
# http://unicorn.bogomips.org/Unicorn/Configurator.html
preload_app true
timeout 30
# This is where we specify the socket.
# We will point the upstream Nginx module to this socket later on
listen "/tmp/unicorn.sock", :backlog => 64
pid "/tmp/unicorn.pid"
# Set the path of the log files inside the log folder of the testapp
stderr_path "#{@app_path}/log/unicorn.stderr.log"
stdout_path "#{@app_path}/log/unicorn.stdout.log"
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
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
sleep 1
end
after_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end
Unicorn 起動
bundle exec unicorn_rails -c config/unicorn.rb -E development -D
vagrant 環境下にてport は1234にしましたので
で表示されました。
Unicorn 起動で下記エラー発生
->> bundle exec unicorn_rails -c config/unicorn.rb -E development -D
master failed to start, check stderr log for details
このような場合は言われた通りにしましょう。
vi ./log/unicorn.stderr.log
I, [2018-01-17T23:20:05.406296 #5849] INFO -- : Refreshing Gem list
NoMethodError: undefined method `load_defaults' for #<Rails::Application::Configuration:0x007fe1f333db28>
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/railties-5.0.6/lib/rails/railtie/configuration.rb:95:in `method_missing'
/usr/share/nginx/html/config/application.rb:12:in `<class:Application>'
/usr/share/nginx/html/config/application.rb:10:in `<module:Stu>'
/usr/share/nginx/html/config/application.rb:9:in `<top (required)>'
/usr/share/nginx/html/config/environment.rb:2:in `require_relative'
/usr/share/nginx/html/config/environment.rb:2:in `<top (required)>'
config.ru:4:in `require_relative'
config.ru:4:in `block in <main>'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/rack-2.0.3/lib/rack/builder.rb:55:in `instance_eval'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/rack-2.0.3/lib/rack/builder.rb:55:in `initialize'
config.ru:1:in `new'
config.ru:1:in `<main>'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn.rb:56:in `eval'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn.rb:56:in `block in builder'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/bin/unicorn_rails:139:in `call'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/bin/unicorn_rails:139:in `block in rails_builder'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:795:in `call'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:795:in `build_app!'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:139:in `start'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/bin/unicorn_rails:209:in `<top (required)>'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/bin/unicorn_rails:23:in `load'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/bin/unicorn_rails:23:in `<top (required)>'
とあるので、
INFO -- : Refreshing Gem list
NoMethodError: undefined method `load_defaults' for #
load_defaults 左記関数が使えないらしい、
rails 5.1かららしいので、
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Stu
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.1 <- 左記関数をコメントアウト
# config.load_defaults 5.1 こんな感じにします。
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
end
end
すると解決できます。
I, [2018-01-17T23:28:36.570446 #6019] INFO -- : Refreshing Gem list
I, [2018-01-17T23:28:38.978489 #6019] INFO -- : listening on addr=/tmp/unicorn.sock fd=13
E, [2018-01-17T23:28:39.331016 #6019] ERROR -- : Access denied for user 'root'@'localhost' (using password: NO) (Mysql2::Error)
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/mysql2-0.4.10/lib/mysql2/client.rb:89:in `connect'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/mysql2-0.4.10/lib/mysql2/client.rb:89:in `initialize'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/mysql2_adapter.rb:25:in `new'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/mysql2_adapter.rb:25:in `mysql2_connection'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/abstract/connection_pool.rb:729:in `new_connection'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/abstract/connection_pool.rb:773:in `checkout_new_connection'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/abstract/connection_pool.rb:752:in `try_to_checkout_new_connection'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/abstract/connection_pool.rb:713:in `acquire_connection'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/abstract/connection_pool.rb:490:in `checkout'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/abstract/connection_pool.rb:364:in `connection'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/abstract/connection_pool.rb:883:in `retrieve_connection'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_handling.rb:128:in `retrieve_connection'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/activerecord-5.0.6/lib/active_record/connection_handling.rb:91:in `connection'
config/unicorn.rb:25:in `block in reload'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:543:in `call'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:543:in `spawn_missing_workers'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:142:in `start'
/usr/share/nginx/html/vendor/bundle/ruby/2.2.0/gems/unicorn-5.4.0/bin/unicorn_rails:209:in `<top (required)>'
DBにアクセスできないらしいので、
vi config/database.yml
# MySQL. Versions 5.1.10 and up are supported.
#
# Install the MySQL driver
# gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
# gem 'mysql2'
#
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.7/en/old-client.html
#
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: ユーザーの名前
password: パスワードを入力
socket: /var/lib/mysql/mysql.sock
development:
<<: *default
database: stu_development
test:
<<: *default
database: stu_test
これでDBへ接続できますので、
解決です。