3
votes

When I point my browser to "rails_app.com", I can view rails_app/public/index.html on the EC2 instance, but when I delete rails_app/public/index.html I get the nginx 403 error,

      directory index of "/home/www-data/rails_app/public/" is forbidden, 

instead of being able to see my Rails 3.0.3 rails_app. I'm using

Nginx Version 0.8.54
Unicorn_rails Version 3.4.0

One post I read said that I need to make sure that the correct version of ruby is available for user www-data, which I did. I have the directory owners for the rails_app set for user and group to www-data, and the permissions set to 775. I can see that the HTTP requests are reaching nginx by looking at the access log. I have DNS setup for my domain name, "rails_app.com" to point to an AWS Elastic IP address which is the Elastic IP of the EC2 instance that I am running nginx + unicorn with my rails app on.

I think I solved this 403 error above as described in Update 2 below. Now I get a 500 error. I fixed the 500 error, as described in Update 4 below.

I am runnng nginx with

/usr/sbin/nginx -c /home/www-data/rails_app/config/nginx.conf

and I am running unicorn with

bundle exec unicorn_rails -p 8000 -E production -c /home/www-data/rails_app/config/unicorn.rb -D

Here is my unicorn.rb:

worker_processes 1
preload_app true
main_dir = '/home/www-data/rails_app'
working_directory '/home/www-data/rails_app'
listen 8000, :tcp_nopush => true
listen "/tmp/shop.socket", :backlog => 2048
timeout 30
user 'www-data'
shared_path = "#{main_dir}/shared"
pid "#{shared_path}/pids/unicorn.pid"
stderr_path "#{shared_path}/log/unicorn.stderr.log"
stdout_path "#{shared_path}/log/unicorn.stdout.log"

UPDATE 1 - I simplified my nginx.conf, after reading this link on Nginx Pitfalls. Here is my nginx.conf:

UPDATE 2 - This post, said that having $uri/ in try_files causes the 403 error, because nginx can't list the directory. So I removed $uri/ from try_files and now I get a 500 error, with nothing showing up in the nginx or unicorn error logs. Any ideas how to debug this?

user www-data www-data;
worker_processes 2;
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
  worker_connections  1024;
  accept_mutex on;
}

http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;
  sendfile    on;

  tcp_nopush  on;
  tcp_nodelay off;

  keepalive_timeout   65;
  client_body_timeout 120;
  upstream app_server {
 #   server 127.0.0.1:8000 fail_timeout=0;
    server unix:/tmp/shop.socket fail_timeout=0;
  } 

  log_format main '\$remote_addr - \$remote_user [\$time_local] \$request '
                  '"\$status" \$body_bytes_sent "\$http_referer" '
                  '"\$http_user_agent" "\$http_x_forwarded_for"';

  access_log /var/log/nginx/access.log main;

  server {
    listen 0.0.0.0:80 ;
    server_name rails_app.com *.rails_app.com;
    index index.html index.htm index.php;
    root /home/www-data/rails_app/public;

    client_max_body_size 50M;

    location /    {
      try_files $uri/index.html $uri.html $uri @app;
    }

    location @app    {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://app_server;

    }   # location /

    error_page 500 502 503 504 /500.html;
    location = /50x.html {
        root /home/www-data/rails_app/public;
    }

 }  # server

}   # http

Using a TCP port for unicorn, I can see that unicorn is listening using

netstat -natp

Now the error I get is the 500.html page displayed:

   We're sorry, but something went wrong.

There are no errors in the nginx error logfile or in the unicorn error log file.

Update 3 -

As I dig into this more, I think the problem might be with unicorn. When I run the rails app at this example, it works fine, but that rails app is using sqlite3 instead of mysql. Also this example allows for zero downtime deployment, by using the before_fork and after_fork code here:

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

 after_fork do |server, worker|
   defined?(ActiveRecord::Base) and
     ActiveRecord::Base.establish_connection
 end

When I try to run my rails_app with mysql and using the before_fork, after_fork code above in my unicorn.rb file, it fails and I get the error:

active_record/connection_adapters/abstract/connection_pool.rb:316:in `retrieve_connection': ActiveRecord::ConnectionNotEstablished (ActiveRecord::ConnectionNotEstablished)

Update 4 -

I added -d (debug) to the unicorn_rails command line as

bundle exec unicorn_rails -p 8000 -E production -c /home/www-data/rails_app/config/unicorn.rb -d -D  

and found a number of errors, the first being that config/application.rb was missing config.secret_token. Added that and continue to debug.

3

3 Answers

1
votes

Finally got it working. The final problem was that Unicorn was complaining that there were no routes for "/". Running 'bundle exec rake routes' produced nothing. Once 'bundle exec rake routes' produced routes, as explained here, then the website came up.

0
votes

It seems to me that failing to set 'preload_app true' in your config file might trigger this.

0
votes

I'm getting the same problem. I was actually able to go around it temporarily by running webrick from the app directory ($ rails s) and then hit my server at port 3000 (http://example.com:3000).

p.s. is the unicorn.log file supposed to loop/scroll without stopping? Seems odd to me when I'm not hitting the app.