Nginx reverse proxy for two webapplications

Solution 1:

Your design is a bit complex and therefore fragile. However, you can try the following. I added upstream blocks so that the different proxy_pass destinations are more readable.

upstream website {
    server 127.0.0.1:8000;
}

upstream application {
    server 127.0.0.1:8080;
}

server {
    server_name example.com *.example.com;

    listen 80;

    # Application catch-all
    location / {
        proxy_pass http://application;
    }

    # Website
    location = / {
        proxy_pass http://website;
    }

    location /news {
        proxy_pass http://website;
    }

    location /about {
        proxy_pass http://website;
    }
}

The = character means an exact match on the URI, and is the first priority in nginx lookup process as described in nginx documentation

An alternative approach is to use regular expression:

server {
    server_name example.com *.example.com;

    listen 80;

    location / {
        proxy_pass http://application;
    }

    location ~ ^(?:/|/news|/about) {
        proxy_pass http://website;
    }
}

The server_name example.com *.example.com tells nginx to process all requests to main domain and any subdomain with these rules.

If the website request rules need to apply only to example.com, then you need to define another server block with server_name *.example.com and application rules only.

Edit

Yes, subdomain can be captured to a variable like that, and used in proxy_pass destination. You need to have all domains in single server_name line:

server_name example.com ~^(?<subdomain>[^.]+)\.example\.com;