0

I've got a VPS that I've been using to experiment with web server setups. My current setup is Apache listening on port 80 serving a few sites, and proxying a few others to Nginx running on port 8080.

I'm running Ubuntu 10.04 with latest updates, but compiled Nginx v0.7.67 myself with uWSGI support.

An excerpt from my Nginx config:

 server {
    listen 127.0.0.1:8080;
    server_name sub1.primary.com;

    access_log /srv/www/sub1.primary.com/logs/access.log;
    error_log /srv/www/sub1.primary.com/logs/error.log;

    location /site_media/static/ {
            alias /srv/www/sub1.primary.com/site_media/static/;
    }

    location / {
            include uwsgi_params;
            uwsgi_pass 127.0.0.1:9001;
    }
  }

server {
    listen 127.0.0.1:8080;
    server_name .secondary.com;


    access_log /srv/www/secondary.com/site_media/logs/access.log;
    error_log /srv/www/secondary.com/site_media/logs/error.log;

    location / {
            alias /srv/www/secondary.com/site_media/static/;
    }
  }

When I have only the first server directive, everything works as expected. When I add the second one the first one continues to work as it was, but the domains for secondary.com bring up the site I've got running at sub1.primary.com. If I then disable the first one, I can access the stuff at secondary.com.

I'm only hosting static files at secondary.com, which is why I'm not using index in location.

I mention proxying from Apache for the sake of completeness, but since I'm seeing a site that Nginx is serving, I assume the problem lies there. What am I missing here?

Edit:

Turns out the thing I was missing is the ProxyPreserveHost On command in my Apache configs, which is off by default.

John Debs
  • 287
  • 1
  • 4
  • 10

2 Answers2

3

Nginx seems to be unable to determine which virtual host should serve your incoming requests. Personally, I would look at the requests forwarded by apache to nginx and check the Host header(since apache must forward the original host header to nginx).

Try tcpdump between the two, with something like this:

tcpdump -s 16436 -SvnXi lo tcp and port 8080

In Apache, you can also configure the custom logs to log the Host header value. Try this out (not tested, from apache doc here)

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Host}i\" " combined
CustomLog log/header_log combined
Julien Vehent
  • 3,017
  • 19
  • 26
  • Thanks for the help. The tcpdump command worked great. I edited my question with the answer I eventually discovered. – John Debs Sep 05 '10 at 02:28
0

Nginx works by specificity for most things, this means that it will hash all the server blocks and try to find the most appropriate one. If no matching server block is found it will use the first one defined.

Which, as Julien sneaked in before I could finish writing this, probably means Apache isn't proxying the HOST header properly.

As a small aside, you can make your configuration file a bit cleaner.

server {
    listen 127.0.0.1:8080;
    server_name sub1.primary.com;

    access_log /srv/www/sub1.primary.com/logs/access.log;
    error_log /srv/www/sub1.primary.com/logs/error.log;

    root /srv/www/sub1.primary.com;

    try_files $uri $uri/ @backend;

    location @backend {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:9001;
    }
  }

server {
    listen 127.0.0.1:8080;
    server_name .secondary.com;

    access_log /srv/www/secondary.com/site_media/logs/access.log;
    error_log /srv/www/secondary.com/site_media/logs/error.log;

    root /srv/www/secondary.com/site_media/static
}
Martin Fjordvald
  • 7,749
  • 1
  • 30
  • 35