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 the below config file for nginx. The problem is all traffic is going to upstream clustera. How do I configure nginx to only send traffic for example.com to clustera and all the rest to clusterb?

user www-data;
worker_processes  1;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    log_format cache '\n*** $remote_addr [$time_local] '
             '[$upstream_cache_status] $upstream_response_time '
             '$host "$request" ($status) $body_bytes_sent '
             '"$http_referer"  "$http_user_agent" '
             'Cache-Control: $upstream_http_cache_control '
             'Expires: $upstream_http_expires '
             ;

    access_log  /var/log/nginx/access.log cache;
    sendfile        on;
    keepalive_timeout  65;


    gzip    on;
    gzip_vary       on;
    gzip_comp_level 6;
    gzip_proxied    any;

    gzip_disable    "MSIE [1-6]\.(?!.*SV1)";
    gzip_buffers    16 8k;

    include /etc/nginx/conf.d/*.conf;

    proxy_cache_key "$scheme$host$request_uri";
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=main:10m max_size=1g inactive=30m;


    upstream clustera {
        ip_hash;
        server  a.example.com:80;
    }
    upstream clusterb {
        ip_hash;
        server  b.example.com:80;
    }


    client_max_body_size    20m;
    client_body_buffer_size 128k;
    proxy_connect_timeout      300;
    proxy_send_timeout         300;
    proxy_read_timeout         300;

    # host for example.com should send traffic to clustera
    server {
        listen 80;
        server_name example.com;

        location ~*(png|jpeg|jpg|gif|ico|css|js)$ {
            proxy_pass      http://clustera;
            proxy_set_header        Host             $host;
            proxy_set_header        X-Real-IP        $remote_addr;
            proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;

            proxy_cache     main;
            proxy_cache_valid       200 5m;
            proxy_cache_valid       302 1m;
        }

        location / {
            proxy_pass http://clustera;
            proxy_set_header        Host             $host;
            proxy_set_header        X-Real-IP        $remote_addr;
            proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

    }
    # host for everyone else. traffic goes to clusterb
    server {
        listen 80;
        server_name _;

        if ( $http_user_agent ~* (spider|crawler|slurp) ) {
             return 503;
        }

        set $slow 0;
        if ( $http_user_agent ~* (bot) ) {
             set $slow 1;
        }

        if ( $slow ) {
           set $limit_rate 1k;
        }

        location ~*(png|jpeg|jpg|gif|ico|css|js)$ {
            proxy_pass      http://clusterb;

            proxy_set_header        Host             $host;
            proxy_set_header        X-Real-IP        $remote_addr;
            proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;


            proxy_cache     main;
            proxy_cache_valid       200 5m;
            proxy_cache_valid       302 1m;
        }

        location /images {
            proxy_pass      http://clisterb;

            proxy_set_header        Host             $host;
            proxy_set_header        X-Real-IP        $remote_addr;
            proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;

            proxy_cache     main;
            proxy_cache_valid       200 5m;
            proxy_cache_valid       302 1m;
        }

        location / {
            proxy_pass http://clusterb;

            proxy_set_header        Host             $host;
            proxy_set_header        X-Real-IP        $remote_addr;
            proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

    }
}
share|improve this question

1 Answer 1

up vote 1 down vote accepted

server_name _ is not a default name server. It literally mean match hostname "_". Obviously this hostname is not valid so you'll never see it, thus your server block will never be used.

If you want to create a catch-all server block then you should use the default_server (default pre 0.8.21) of the listen directive.

The reason a lot of guides online mislead you into believing this is because they always place it first, which is what Nginx falls back to if no default server block is provided, then they make the logical deduction that because every one else says so it must be true.

Of course, reading the official documentation or the server_name wiki entry would immediately enlighten you.

share|improve this answer
    
Worked perfectly, thanks! –  Morgan Jun 24 '11 at 15:27

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.