I'm having some trouble getting my rails app to run in production. As I've coded rails before but haven't deployed much it's probably something in my configs and/or deployment process.
Everything runs fine locally in development. All tests pass, I can see the routes and access them at localhost. When in production (rails 4, nginx, unicorn on CentOS) I'm getting 500 errors on the very same routes.
When I rake routes on the server I see all the same routes as when in development. Rake routes on the server returns (shortened from the full list of routes):
Prefix Verb URI Pattern Controller#Action
companies GET /companies(.:format) companies#index
POST /companies(.:format) companies#create
new_company GET /companies/new(.:format) companies#new
edit_company GET /companies/:id/edit(.:format) companies#edit
company GET /companies/:id(.:format) companies#show
PATCH /companies/:id(.:format) companies#update
PUT /companies/:id(.:format) companies#update
DELETE /companies/:id(.:format) companies#destroy
Which as you can probably guess comes from resources :companies
But http://sortinghat.foo.com/companies gives me the rails 500 page on production (foo is obviously not the domain but I've just replaced the real domain).
I am at a loss having searched on here and the web for ideas, having read lots of "how to deploy rails" blog posts, and have looked at lots of config files (you'll see these are ones I copied from elsewhere but it all seems pretty standard). I'm probably missing something obvious. I'm not seeing any issues in the logs.
The only clue I have is that I don't have an /etc/nginx/sites-enabled directory and it looks like capistrano wants one, but I didn't see any errors during cap deploy (except the cleanup one I note at the bottom). In this case it's the only site being run so I don't need a virtual host and didn't think I needed it so wasn't concerned.
Thanks in advance for any help.
Here's my nginx.config
# Taken from http://www.sitepoint.com/deploying-your-rails-app-to-the-cloud-with-unicorn-nginx-and-capistrano/
upstream unicorn {
server unix:/tmp/unicorn.sortinghat.sock fail_timeout=0;
}
server {
listen 80 default deferred;
server_name sortinghat;
if ($host = 'sortinghat' ) {
rewrite ^/(.*)$ http://sortinghat.foo.com/$1 permanent;
}
root /var/www/sortinghat/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri @unicorn;
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
My unicorn.rb
# Taken from http://www.sitepoint.com/deploying-your-rails-app-to-the-cloud-with-unicorn-nginx-and-capistrano/
# Define your root directory
root = "/var/www/sortinghat/current"
# Define worker directory for Unicorn
working_directory root
# Location of PID file
pid "#{root}/tmp/pids/unicorn.pid"
# Define Log paths
stderr_path "#{root}/log/unicorn.log"
stdout_path "#{root}/log/unicorn.log"
# Listen on a UNIX data socket
listen "/tmp/unicorn.sortinghat.sock"
# 16 worker processes for production environment
worker_processes 16
# Load rails before forking workers for better worker spawn time
preload_app true
# Restart workes hangin' out for more than 240 secs
timeout 240
And my deploy.rb (Note: I made some things world readable with the chmod 777 as a quick hack. I'm just trying to get this running internally to run a test all behind a firewall. I can probably take those out but I doubt they're hurting anything right now.)
require 'capistrano/ext/multistage'
set :application, "sortinghat"
# Need to use gnutar since that is what the server uses
# see https://coderwall.com/p/ypwmpg
set :copy_local_tar, "/usr/bin/gnutar" if `uname` =~ /Darwin/
# remove old releases
set :keep_releases, 3
# Source Control
# You can set :scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
set :repository, "[email protected]:me/project.git" # changed here but correct in the actual file
set :scm, :git
set :branch, "master"
set :deploy_via, :copy
# Deployment
# Default deployment directory is /u/apps/#{application}” (where #{application} but alternate can be set
# set :deploy_to, "/var/www"
set :user, "mherschberg"
default_run_options[:pty] = true
set :use_sudo, false
set :ssh_options, {:forward_agent => true}
role :web, "sortinghat.foo.com" # Your HTTP server, Apache/etc
role :app, "sortinghat.foo.com" # This may be the same as your `Web` server
role :db, "lin-db3.foo.com", :primary => true #, :no_release => true # This is where Rails migrations will run
#role :db, "your slave db-server here" # no slave for test
set :rails_env, "production"
set :stages, ["staging", "production"]
set :default_stage, "staging"
# if you want to clean up old releases on each deploy uncomment this:
after "deploy:restart", "deploy:cleanup"
namespace :deploy do
%w[start stop restart].each do |command|
desc "#{command} unicorn server"
task command, roles: :app, except: {no_release: true} do
sudo "chmod 777 /var/www/sortinghat/current/config/unicorn_ini.sh"
run "/etc/init.d/unicorn_#{application} #{command}" # Using unicorn as the app server
end
end
task :setup_config, roles: :app do
sudo "ln -nfs #{current_path}/config/nginx.conf /etc/nginx/sites-enabled/#{application}"
sudo "ln -nfs #{current_path}/config/unicorn_ini.sh /etc/init.d/unicorn_#{application}"
sudo "chmod 777 #{current_path}/config/unicorn_ini.sh"
sudo "chmod 777 /var/www/sortinghat/current/config/unicorn_ini.sh"
run "mkdir -p #{shared_path}/config"
put File.read("config/database.yml"), "#{shared_path}/config/database.yml"
puts "Now edit the config files in #{shared_path}."
end
after "deploy:setup", "deploy:setup_config"
task :symlink_config, roles: :app do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end
after "deploy:finalize_update", "deploy:symlink_config"
desc "Make sure local git is in sync with remote."
task :check_revision, roles: :web do
unless `git rev-parse HEAD` == `git rev-parse origin/master`
puts "WARNING: HEAD is not the same as origin/master"
puts "Run `git push` to sync changes."
exit
end
end
before "deploy", "deploy:check_revision"
end
# if you're still using the script/reaper helper you will need
# these http://github.com/rails/irs_process_scripts
# If you are using Passenger mod_rails uncomment this:
# namespace :deploy do
# task :start do ; end
# task :stop do ; end
# task :restart, :roles => :app, :except => { :no_release => true } do
# run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
# end
# end
cap deploy works with only one error, but it's just a problem with permissions cleaning up old releases. ( cap deploy:cold ran fine)
** [out :: sortinghat.foo.com] rm: cannot remove `/var/www/sortinghat/releases/20130917180205/thout-curl-include=dir/include/build_info': Permission denied