2

I'm serving a webservice (API + Webiste) through nginx and its canonical domain name changed recently. The API is split from the user-facing website by subdirectories (eg /api/ and /download/ are part of the API, the rest belongs to the website).

I'd now like to redirect the website-part to the new domainname but serve the API requests without redirects (to keep server load down).

Because the webserver can be accessed through a number of domains, I'd need to redirect everything that doesn't match the new canonical one; something like

IF request-domain != new-domain
 AND resource not in (/api/, /download/):
   redirect to new domain

ELSE:
   # serve site
   proxy_pass   http://app_server;

I didn't find a way suitable way in nginx to do the (double) negative comparison, and I can't invert them to a positive comparison, because both alternative domain names and non-API resources are quite a lot that I don't want to maintain in the nginx config.

Any ideas would be highly appreciated!

2 Answers 2

8

In nginx, you generally don't want to use if for changing behavior based on Host header or uri. You need a second server:

server {
  # Make sure this listen matches the one in the second server (minus default flag)
  listen 80;

  server_name new-domain;

  # All your normal processing.  Is it just proxy_pass?
  location / {
    proxy_pass http://app_server;
  }
}

server {
  # If you listen on a specific ip, make sure you put it in the listen here
  # default means it'll catch anything that doesn't match a defined server name
  listen 80 default;

  server_name old-domain; # and everything else, but it's good to define something

  # Everything that doesn't match /api/ or /download/
  location / {
    rewrite ^ http://new-domain$request_uri? permanent;
  }

  # You may want some common proxy_set_header lines here in the server
  # if you need them

  location /api/ {
    proxy_pass http://app_server;
  }

  location /download/ {
    proxy_pass http://app_server;
  }
}
0
0

Nginx doesn't allow multiple or nested if statements but you can set variables, something like this:

    server_name _;

    if ($http_host !~ new-domain) {
        set $var D;
    }
    if ($request_uri !~ (/api|/download)) {
        set $var "${var}U";
    }
    if ($var = DU) {
        rewrite ^(.*)$ http://new-domain$request_uri last;
        break;
    }

About the else condition, you should do it in a separated virtual host.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .