Score:0

Nginx reverse proxy for two webapplications

in flag

I have two applications.

  • Laravel Application - Being just a dynamic website. Does not have data-knowledge. All the data gets fetched from the second application using AJAX-requests. Runs on 127.0.0.1:8000.
  • Rust Application - A web-application containing all the business logic and data-access. Runs on 127.0.0.1:8080.

Both applications need to be accessible from the URL example.com. For this I want to use Nginx Reverse Proxy. I am already able to reroute all requests to my Laravel Application.

events {}
http {
    server {
        listen 80;

        # Website
        location / {
            proxy_pass http://127.0.0.1:8000;
        }
        
    }
}

While the Laravel Application works, I need actually need the following Nginx configuration:

  • Specific pages like /news, /, /about,/contact,... should be redirected to 127.0.0.1:8000.
  • Note: The pages above can contain GET-parameters like e.g /news?article=abc.
  • ALL other requests need to be redirected to 127.0.0.1:8080.
  • Note: 127.0.0.1:8080 can often contain a subdomain. But this subdomain needs to act like a wildcard and is unknown at the time of configuration. Example: bussiness1.example.com, bussiness2.example.com, businnesX.example.com,...

The subdomain returns a personalized page for which an unlimited amount of businesses can request for on example.com.

How would I achieve this configuration? I was thinking something like this?

#PSEUDO
events {}
http {
    server {
        listen 80;

        # Website
        location / {
            proxy_pass http://127.0.0.1:8000;
        }
        location /news {
            proxy_pass http://127.0.0.1:8000;
        }
        location /about {
            proxy_pass http://127.0.0.1:8000;
        }

        # Application
        location * {
            proxy_pass http://127.0.0.1:8080;
        }

    }
}

Edit regarding Tero's answer: I need a kind of wildcard for subdomains.

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

abc.example.com needs to go to abc.127.0.0.1:8080 def.example.com needs to go to def.127.0.0.1:8080 ...

I know an IP can't have a subdomain but don't worry about that. I solved that with virtual hosts.

Edit 2 - Pass subdomain of request to proxy_pass:

server {
        listen 80;
        server_name *.website.com;
        server_name ~^(?<subdomain>.+)\.website\.com$;

        location / {
            proxy_pass http://$subdomain.vhost.local:8080;
        }
    }

Is this the correct way to redirect dynamicxxx.website.com to dynamicxxx.vhost.local:8080?

djdomi avatar
za flag
i think you have to replace star with tilde
Score:2
us flag

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;
O'Niel avatar
in flag
Thanks a lot for your reply! This is getting close. However, the Catch-all for the application also needs to handle subdomains. Is a kind of wildcard possible? See post edit.
us flag
Then you need to do a second `server` block for the subdomains with `server_name *.example.com`.
O'Niel avatar
in flag
Thanks for all the help! Explained it a lot. If you could only look again at my second edit? Regarding the subdomain wildcard.
O'Niel avatar
in flag
I'm really close mate. Only the subdomain wildcard remains.
us flag
I added a `server_name` example.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.