无法在EC2上使用nginx + unicorn为Rails 3应用程序提供服务

时间:2012-01-30 05:24:24

标签: ruby-on-rails-3 nginx amazon-ec2 unicorn

当我将浏览器指向“rails_app.com”时,我可以在EC2实例上查看rails_app / public / index.html,但是当我删除rails_app / public / index.html时,我得到了nginx 403错误,

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

而不是能够看到我的Rails 3.0.3 rails_app。我正在使用

Nginx Version 0.8.54
Unicorn_rails Version 3.4.0

我读过的一篇帖子说我需要确保用户www-data可以使用正确版本的ruby,我这样做了。我有rails_app的目录所有者为用户和组设置为www-data,权限设置为775.我可以通过查看访问日志看到HTTP请求到达nginx。我为我的域名设置了DNS设置,“rails_app.com”指向一个AWS弹性IP地址,它是EC2实例的弹性IP,我在我的rails应用程序上运行nginx + unicorn。

我认为我解决了上面的403错误,如下面的更新2中所述。现在我得到500错误。我修正了500错误,如下面的更新4中所述。

我用

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

我正在用

运行独角兽
bundle exec unicorn_rails -p 8000 -E production -c /home/www-data/rails_app/config/unicorn.rb -D

这是我的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"

更新1 - 在Nginx陷阱上阅读此link之后,我简化了我的nginx.conf。 这是我的nginx.conf:

UPDATE 2 - 这个post表示拥有$ uri / in try_files会导致403错误,因为nginx无法列出目录。所以我从try_files中删除了$ uri /,现在我得到了500错误,nginx或unicorn错误日志中没有显示任何内容。任何想法如何调试这个?

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

使用TCP端口进行独角兽,我可以看到独角兽正在使用

进行侦听
netstat -natp

现在我得到的错误是显示的500.html页面:

   We're sorry, but something went wrong.

nginx错误日志文件或独角兽错误日志文件中没有错误。

更新3 -

当我更深入地研究这个问题时,我认为问题可能出在独角兽身上。当我在这个example运行rails应用程序时,它工作正常,但rails应用程序使用的是sqlite3而不是mysql。此示例还允许零停机时间部署,在此处使用before_fork和after_fork代码:

 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

当我尝试使用mysql运行我的rails_app并使用我的unicorn.rb文件中的before_fork,after_fork代码时,它失败并且我收到错误:

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

更新4 -

我将-d(debug)添加到unicorn_rails命令行作为

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

并发现了一些错误,第一个是config / application.rb缺少config.secret_token。添加并继续调试。

3 个答案:

答案 0 :(得分:1)

终于搞定了。最后一个问题是Unicorn抱怨没有“/”路线。运行'bundle exec rake routes'什么都没产生。一旦'捆绑执行耙路线'产生了路线,如here所述,那么网站出现了。

答案 1 :(得分:0)

在我看来,未能在配置文件中设置'preload_app true'可能会触发此操作。

答案 2 :(得分:0)

我遇到了同样的问题。我实际上可以通过从应用程序目录($ rails s)运行webrick然后在端口3000(http://example.com:3000)上点击我的服务器来暂时解决它。

P.S。是unicorn.log文件应该循环/滚动而不停止?当我没有点击应用程序时,对我来说似乎很奇怪。