Configuring nginx server to handle requests from multiple domains

KillABug picture KillABug · Nov 12, 2013 · Viewed 9.1k times · Source


Use Case:- I am working on a web application which allows to create HTML templates and publish them on amazon S3.Now to publish the websites I use nginx as a proxy server. What the proxy server does is,when a user enters the website URL,I want to identify how to check if the request comes from my application i.e app.mysite.com(This won't change) and route it to apache for regular access,if its coming from some other domain like a regular URL www.mysite.com(This needs to be handled dynamically.Can be random) it goes to the S3 bucket that hosts the template.

My current configuration is:

user  nginx;
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;
default_type  application/octet-stream;

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;

charset   utf-8;
keepalive_timeout  65;
server_tokens       off;
sendfile            on;
tcp_nopush          on;
tcp_nodelay         off;

Default Server Block to catch undefined host names

    server {
      listen 80;
      server_name  app.mysite.com;

       access_log  off;
       error_log off;

      location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        Host            $host;
        proxy_redirect          off;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout 90;
        proxy_send_timeout 90;
        proxy_read_timeout 90;
        client_max_body_size 10m;
        client_body_buffer_size 128k;
        proxy_buffer_size 4k;
        proxy_buffers 4 32k;
        proxy_busy_buffers_size 64k;
      }
 }

}

Load all the sites

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


Updates as I was not clear enough :-
My question is how can I handle both the domains in the config file.My nginx is a proxy server on port 80 on an EC2 instance.This also hosts my application that runs on apache on a differnet port.So any request coming for my application will come from a domain app.mysite.com and I also want to proxy the hosted templates on S3 which are inside a bucket say sites.mysite.com/coolsite.com/index.html.So if someone hits coolsite.com I want to proxy it to the folder sites.mysite.com/coolsite.com/index.html and not to app.syartee.com.Hope I am clear
The other server block:

     # Server for S3
server {
    # Listen on port 80 for all IPs associated with your machine
    listen 80;

    # Catch all other server names
    server_name _; //I want it to handle other domains then app.mysite.com

    # This code gets the host without www. in front and places it inside
    # the $host_without_www variable
    # If someone requests www.coolsite.com, then $host_without_www will have the value coolsite.com
    set $host_without_www $host;
    if ($host ~* www\.(.*)) {
       set $host_without_www $1;

    }

    location / {
        # This code rewrites the original request, and adds the host without www in front
        # E.g. if someone requests
        # /directory/file.ext?param=value
        # from the coolsite.com site the request is rewritten to
        # /coolsite.com/directory/file.ext?param=value
        set $foo 'http://sites.mysite.com';
       # echo "$foo";
        rewrite ^(.*)$ $foo/$host_without_www$1 break;


        # The rewritten request is passed to S3
         proxy_pass http://sites.mysite.com;
         include /etc/nginx/proxy_params;
   }
}

Also I understand I will have to make the DNS changes in the cname of the domain.I guess I will have to add app.mysite.com under the CNAME of the template domain name?Please correct if wrong.

Thank you for your time

Answer

KillABug picture KillABug · Nov 18, 2013

Found this as a part of documentation but took a while to understand. I had to add a default_server attribute in the second server block for rest of the domains to work.
If we config the server_name, nginx will serve the content based on config block that match the domain.

app.mysite.com

server {
  listen 80;
  server_name  app.mysite.com;

  # config for app.mysite.com

}

other websites

server {
  listen 80 default_server; #To handle domains apart from the fixed domain(In my case app.mysite.com)
  server_name _ ;

  # config for coolsite.com, anotherdomain.com ...

}