【问题标题】:Trouble serving Rails 3 app with nginx + unicorn on EC2在 EC2 上使用 nginx + unicorn 为 Rails 3 应用程序提供服务时遇到问题
【发布时间】:2012-01-30 05:24:24
【问题描述】:

当我将浏览器指向“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。我为我的域名“rails_app.com”设置了 DNS,以指向一个 AWS 弹性 IP 地址,该地址是我在 rails 应用程序上运行 nginx + unicorn 的 EC2 实例的弹性 IP。

我想我解决了上面的这个 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 Pitfalls 的 link 之后,我简化了我的 nginx.conf。 这是我的 nginx.conf:

UPDATE 2 - 这个post,说在try_files 中有$uri/ 会导致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

使用 unicorn 的 TCP 端口,我可以看到 unicorn 正在监听使用

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 -

我在 unicorn_rails 命令行中添加了 -d(调试)

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。已添加并继续调试。

【问题讨论】:

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


    【解决方案1】:

    终于搞定了。最后一个问题是 Unicorn 抱怨“/”没有路由。运行 'bundle exec rake routes' 没有产生任何结果。一旦 'bundle exec rake routes' 产生了路由,正如 here 解释的那样,然后网站就出现了。

    【讨论】:

    • 为我指明了正确的方向。就我而言,我从 try_files 行中删除了“$uri/”,它起作用了。
    【解决方案2】:

    在我看来,未能在您的配置文件中设置 'preload_app true' 可能会触发此问题。

    【讨论】:

    • dmw - 你在句子末尾的代词 -this- 指的是什么?当我包含 before_fork 和 after_fork 代码时,我的 unicorn.rb 配置文件中确实有 preload_app true,但在 connection_pool.rb 中仍然出现 ConnectionNotEstablished 错误。
    • 是的,这就是我所指的。由于 preload_app 对您来说是正确的,显然问题有不同的原因。
    【解决方案3】:

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

    附言unicorn.log 文件是否应该循环/滚动而不停止?当我不点击应用程序时,我觉得这很奇怪。

    【讨论】:

      猜你喜欢
      • 2015-08-15
      • 2023-03-15
      • 2014-02-02
      • 2017-10-25
      • 2014-11-08
      • 2015-05-22
      • 2014-11-06
      • 2023-03-12
      • 2020-09-27
      相关资源
      最近更新 更多