Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struggling with location blocks in nginx config

Tags:

nginx

I got a new slice off slicehost, for the purposes of playing around and learning nginx and more about deployment generally. I installed a ruby app on there (which i'll call app1) which uses passenger. I made it the default app to use for that server with the following server block in my nginx config:

server {
    listen 80;
    server_name <my server ip>;
    root <path to app1 public folder>;
    passenger_enabled on;
}

This works fine. However, i want to try a few different apps out on this slice, and so thought i would set it up like so:

http:///app1

http:///app2

etc. I thought i would be able to do that by adding a location block, and moving the app1 specific stuff into it like so:

server {
    listen 80;
    server_name <my server ip>;

    location ^~ /app1 {
        root <path to app1 public folder>;
        passenger_enabled on;
    }
}

However, on doing this (and restarting nginx of course), going to the plain ip address gives the 'welcome to nginx' message (which i'd expect). But, going to /app1 gives an error message:

404 Not Found
The requested URL /app1 was not found on this server. 

This is distinct from the error message i get when i go to another path on that ip, eg /foo:

404 Not Found
nginx/0.8.53

So, it's like nginx knows about that location but i've not set it up properly. Can anyone set me straight? Should i set up different server blocks instead of using locations? I'm sure this is simple but can't work it out.

Cheers, max

like image 486
Max Williams Avatar asked Dec 16 '22 16:12

Max Williams


1 Answers

What you're after is name virtual hosting. The idea is that each domain is hosted on the same IP, and nginx chooses the virtualhost to serve based on the Host: header in the HTTP request, which is sent by the browser.

To use name virtual hosting, use the domain you want to serve instead of your server's IP for the server_name directive.

server {
  listen 80;
  server_name app1.com;

  location / {
    root /srv/http/app1/public;
    passenger_enabled on;
  }
}

Then, to host more apps on the same box, just declare a separate server { } block for each one.

server {
  listen 80;
  server_name app2.com;

  location / {
    root /srv/http/app2/public;
    passenger_enabled on;
  }
}

I'm using unicorn instead of passenger, but the vhost part of the structure is the same for any backend.

The global nginx config (which on its own hosts nothing): https://github.com/benhoskings/babushka-deps/blob/master/nginx/nginx.conf.erb

The template wrapper for each virtualhost: https://github.com/benhoskings/babushka-deps/blob/master/nginx/vhost.conf.erb

The details of the unicorn virtualhost: https://github.com/benhoskings/babushka-deps/blob/master/nginx/unicorn_vhost.common.erb

like image 164
ben_h Avatar answered Jan 08 '23 10:01

ben_h