1

I have an index.html in public/ that should be loading by default but instead I get a 404 error when I try to access http://example.com/

The page you were looking for doesn't exist.

You may have mistyped the address or the page may have moved.

This has something to do with nginx and unicorn which I am using to power Rails 3

When take unicorn out of the nginx configuration file, the problem goes away and index.html loads just fine.

Here is my nginx configuration file:

upstream unicorn {
    server unix:/tmp/.sock fail_timeout=0;
}

server {
    server_name example.com;
    root /www/example.com/current/public;
    index index.html;

    keepalive_timeout 5;

    location / {
        try_files $uri @unicorn;
    }

    location @unicorn {
        proxy_pass http://unicorn;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }
}

My config/routes.rb is pretty much empty:

Advertise::Application.routes.draw do |map|
  resources :users
end

The index.html file is located in public/index.html and it loads fine if I request it directly: http://example.com/index.html

To reiterate, when I remove all references to unicorn from the nginx conf, index.html loads without any problems, I have a hard time understanding why this occurs because nginx should be trying to load that file on its own by default.

--

Here is the error stack from production.log:

Started GET "/" for 68.107.80.21 at 2010-08-08 12:06:29 -0700
  Processing by HomeController#index as HTML
Completed   in 1ms

ActionView::MissingTemplate (Missing template home/index with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml, :haml], :formats=>[:html], :locale=>[:en, :en]} in view paths
"/www/example.com/releases/20100808170224/app/views", 
"/www/example.com/releases/20100808170224/vendor/plugins/paperclip/app/views", 
"/www/example.com/releases/20100808170224/vendor/plugins/haml/app/views"):
/usr/local/rvm/gems/ruby-1.9.2-rc2/gems/actionpack-3.0.0.beta4/lib/action_view/paths.rb:14:in `find'
  /usr/local/rvm/gems/ruby-1.9.2-rc2/gems/actionpack-3.0.0.beta4/lib/action_view/lookup_context.rb:79:in `find'
  /usr/local/rvm/gems/ruby-1.9.2-rc2/gems/actionpack-3.0.0.beta4/lib/action_view/base.rb:186:in `find_template'
  /usr/local/rvm/gems/ruby-1.9.2-rc2/gems/actionpack-3.0.0.beta4/lib/action_view/render/rendering.rb:45:in `_determine_template'
  /usr/local/rvm/gems/ruby-1.9.2-rc2/gems/actionpack-3.0.0.beta4/lib/action_view/render/rendering.rb:23:in `render'
  /usr/local/rvm/gems/ruby-1.9.2-rc2/gems/haml-3.0.15/lib/haml/helpers/action_view_mods.rb:13:in `render_with_haml'
  etc...

--

nginx error log for this virtualhost comes up empty:

2010/08/08 12:40:22 [info] 3118#0: *1 client 68.107.80.21 closed keepalive connection

My guess is unicorn is intercepting the request to index.html before nginx gets to process it.

2
  • Please add "error_log /path/to/error.log info;" to config and provide any info related to the 404. Aug 8, 2010 at 19:23
  • Looks like the request never reaches nginx in the first place because nginx's error log shows nothing except that it closed a keepalive connection.
    – Miko
    Aug 8, 2010 at 19:43

3 Answers 3

1

Rails 3 does not serve static assets by default. You have to configure your web server to serve up the public server or add

config.serve_static_assets = true

to your production environment http://docs.heroku.com/rails3

1

This seems to work. I had to edit the nginx config file: /etc/nginx/servers/appname.conf

location / {
  ...stuff...

  # check for index.html for directory index
  # if its there on the filesystem then rewite 
  # the url to add /index.html to the end of it
  # and then break to send it to the next config rules.
  if (-f $request_filename/index.html) {
    rewrite (.*) $1/index.html break;
  }

  ...other stuff..

}

Using config.serve_static_assets = true only came up with about half the requests per second as I get after adding this and having config.serve_static_assets = false

1

The problem is here:

    try_files $uri @unicorn;

This should read:

    try_files $uri $uri/ @unicorn;

Which also eliminates the need to use an evil if, and doesn't require you to have Rails serve static files (which is slow).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .