Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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.

share|improve this question
    
Please add "error_log /path/to/error.log info;" to config and provide any info related to the 404. –  Martin Fjordvald Aug 8 '10 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 '10 at 19:43
add comment

3 Answers

up vote 0 down vote accepted

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

share|improve this answer
add comment

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

share|improve this answer
add comment

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).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.