DEV Community

Cover image for Path-Based Routing with Reverse Proxy: Serving Multiple Websites from One Domain
Sanchit Bajaj
Sanchit Bajaj

Posted on

Path-Based Routing with Reverse Proxy: Serving Multiple Websites from One Domain

Hey developers πŸ‘‹

At some point in our development journey, we’ve all played around with domains, subdomains, routes, reverse proxies, and enough DNS records to make us question our life choices.

But here’s an interesting problem:

What if you want a completely different website to appear at a specific path of your existing domain?

Let's say I have a pastry business called My Pastries 🍰.

My main website lives at:

mypastries.com
Enter fullscreen mode Exit fullscreen mode

It is built with Next.js because I want server-side rendering, good performance, solid SEO, and enough flexibility to customize pretty much everything.

Everything is going great. Then I decide:

"We should probably start a blog."

Not just because everyone keeps saying content is king, but because I want to publish useful content, build topical authority, attract organic traffic, and generally give the website more reasons to exist than just "here are our cakes."

Now, I could build the entire blogging system myself.

Or I could save myself the headache and use WordPress or another CMS that already solved most of these problems years ago.

So I deploy my blog separately.

My infrastructure now looks something like this:

172.1.0.1 β†’ Main Next.js website
172.1.0.2 β†’ WordPress/CMS blog
Enter fullscreen mode Exit fullscreen mode

But now comes the interesting part. I don't want users to visit:

blog.mypastries.com
Enter fullscreen mode Exit fullscreen mode

I want them to visit:

mypastries.com/blog
Enter fullscreen mode Exit fullscreen mode

And if they open an article:

mypastries.com/blog/how-to-make-the-perfect-croissant
Enter fullscreen mode Exit fullscreen mode

I want the second server to handle that request.

But I still want the browser to show:

mypastries.com/blog/how-to-make-the-perfect-croissant
Enter fullscreen mode Exit fullscreen mode

No redirect.

No separate domain.

No making the user care where my blog is actually hosted.

So how do I make two completely different servers behave like one website?

This is where reverse proxies and path-based routing come in.


1. What Is a Reverse Proxy?

Let's start with the simplest mental model.

A reverse proxy is a server that sits between the client and one or more backend servers.

Instead of the browser directly talking to my application server, it talks to the reverse proxy.

The reverse proxy then decides where that request actually needs to go.

In our example:

                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚                  β”‚
User ───────────────►│  Nginx           β”‚
                     β”‚  Reverse Proxy   β”‚
                     β”‚                  β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                       β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”
                       β”‚             β”‚
                       β–Ό             β–Ό
                  172.1.0.1      172.1.0.2
                  Main Website     Blog
Enter fullscreen mode Exit fullscreen mode

The important thing here is that the user doesn't need to know about 172.1.0.1 or 172.1.0.2.

As far as the user is concerned, they're talking to:

mypastries.com
Enter fullscreen mode Exit fullscreen mode

Nginx is the one making the decision about which server should actually handle the request.

And this is why reverse proxies are so useful.

I can have:

mypastries.com/
mypastries.com/products
mypastries.com/about
Enter fullscreen mode Exit fullscreen mode

going to one application while:

mypastries.com/blog
mypastries.com/blog/recipes
mypastries.com/blog/my-first-post
Enter fullscreen mode Exit fullscreen mode

goes to another.

From the outside, it looks like one website.

Internally, it can be several completely independent applications.


2. Reverse Proxy vs Redirect

This distinction confused me the first time I started working with proxy configurations, so it's worth making explicit.

A redirect tells the browser:

"Hey, don't request this URL anymore. Go request this other URL."

For example:

Browser
   β”‚
   β”‚ GET /blog
   β–Ό
Server
   β”‚
   β”‚ 301 Redirect
   β–Ό
blog.mypastries.com
Enter fullscreen mode Exit fullscreen mode

The browser receives the redirect and makes another request.

A reverse proxy works differently.

Browser
   β”‚
   β”‚ GET /blog
   β–Ό
Nginx
   β”‚
   β”‚ proxy request
   β–Ό
172.1.0.2
   β”‚
   β”‚ response
   β–Ό
Nginx
   β”‚
   β–Ό
Browser
Enter fullscreen mode Exit fullscreen mode

The browser never needs to know that Nginx forwarded the request somewhere else.

This is the important bit:

The URL stays the same from the user's perspective.

So when the user visits:

mypastries.com/blog/my-first-post
Enter fullscreen mode Exit fullscreen mode

the browser continues to show that URL even if Nginx actually fetched the content from:

172.1.0.2
Enter fullscreen mode Exit fullscreen mode

That's fundamentally different from an HTTP redirect.


3. Path-Based Routing

Now that we understand the reverse proxy part, let's add one more piece:

path-based routing.

The idea is pretty straightforward.

Instead of routing traffic only based on the domain, I can tell Nginx:

"If the request starts with /blog, send it to the blog server."

For example:

Request                                      Destination

mypastries.com/                             β†’ 172.1.0.1
mypastries.com/about                        β†’ 172.1.0.1
mypastries.com/products                     β†’ 172.1.0.1

mypastries.com/blog                         β†’ 172.1.0.2
mypastries.com/blog/recipes                 β†’ 172.1.0.2
mypastries.com/blog/my-first-post           β†’ 172.1.0.2
Enter fullscreen mode Exit fullscreen mode

This is generally called path-based routing.

And once you understand this pattern, you can use it for much more than blogs.

For example:

example.com/       β†’ Main website
example.com/app/   β†’ Application
example.com/api/   β†’ API
example.com/admin/ β†’ Admin panel
example.com/docs/  β†’ Documentation
Enter fullscreen mode Exit fullscreen mode

All of these can potentially live on completely different servers or services.


4. The Architecture

Before touching Nginx, let's make the architecture clear.

I'll use this setup throughout the article:

                        mypastries.com
                              β”‚
                              β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚      Nginx      β”‚
                    β”‚ Reverse Proxy   β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚                         β”‚
             / request                 /blog request
                β”‚                         β”‚
                β–Ό                         β–Ό
          172.1.0.1                  172.1.0.2
          Next.js App                Blog/CMS
Enter fullscreen mode Exit fullscreen mode

The basic rule is:

/       β†’ 172.1.0.1
/blog   β†’ 172.1.0.2
Enter fullscreen mode Exit fullscreen mode

The domain points to the machine running Nginx.

Nginx then acts as the traffic controller.

And importantly, DNS does not perform the /blog routing.

DNS only helps get:

mypastries.com
Enter fullscreen mode Exit fullscreen mode

to the server where Nginx is running.

Once the HTTP request reaches Nginx, Nginx looks at the request path and decides what to do with it.

That's an important distinction.


5. Configuring Nginx

Now let's actually configure it.

For the simplest version, our Nginx configuration can look like this:

server {
    listen 80;
    server_name mypastries.com;

    location / {
        proxy_pass http://172.1.0.1;
    }

    location /blog/ {
        proxy_pass http://172.1.0.2;
    }
}
Enter fullscreen mode Exit fullscreen mode

That's already enough to demonstrate the basic concept.

But let's break it down instead of treating Nginx configuration like ancient magic that must be copied from Stack Overflow without questioning it.

The server block

server {
    listen 80;
    server_name mypastries.com;
}
Enter fullscreen mode Exit fullscreen mode

This tells Nginx that this configuration should handle requests for:

mypastries.com
Enter fullscreen mode Exit fullscreen mode

on port 80.

In a real production deployment, I'd normally be dealing with HTTPS and port 443, but I'm keeping the first example intentionally simple.


The default route

Next:

location / {
    proxy_pass http://172.1.0.1;
}
Enter fullscreen mode Exit fullscreen mode

This basically says:

"For requests matching /, proxy them to 172.1.0.1."

So requests such as:

mypastries.com/
mypastries.com/about
mypastries.com/products
Enter fullscreen mode Exit fullscreen mode

will be handled by the main website.


The blog route

Then I add:

location /blog/ {
    proxy_pass http://172.1.0.2;
}
Enter fullscreen mode Exit fullscreen mode

Now Nginx has a more specific route for requests starting with /blog/.

So:

mypastries.com/blog/
mypastries.com/blog/recipes
mypastries.com/blog/my-first-post
Enter fullscreen mode Exit fullscreen mode

are sent to:

172.1.0.2
Enter fullscreen mode Exit fullscreen mode

This is the basic mechanism we're after.


6. Don't Forget the Forwarded Headers

There is another part of reverse proxy configuration that I wouldn't skip in a real deployment.

The upstream application often needs to know things about the original request:

  • What host did the user request?

  • What was the original client IP?

  • Was the original request HTTPS?

  • What protocol was being used?

Nginx can forward that information through headers.

A more realistic configuration would therefore look like:

location /blog/ {
    proxy_pass http://172.1.0.2;

    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_set_header X-Forwarded-Proto $scheme;
}
Enter fullscreen mode Exit fullscreen mode

These headers are especially useful when the application generates absolute URLs, performs redirects, logs client addresses, or needs to understand whether the original request was HTTP or HTTPS.

I generally prefer setting these explicitly rather than discovering six months later that the application thinks every visitor is coming from my Nginx server.


7. The proxy_pass Trailing Slash Trap

Now we get to one of those Nginx details that looks completely harmless until it ruins your afternoon.

Consider:

location /blog/ {
    proxy_pass http://172.1.0.2;
}
Enter fullscreen mode Exit fullscreen mode

versus:

location /blog/ {
    proxy_pass http://172.1.0.2/;
}
Enter fullscreen mode Exit fullscreen mode

That trailing / matters.

Nginx handles the URI differently depending on how proxy_pass is written.

If I have:

/blog/my-first-post
Enter fullscreen mode Exit fullscreen mode

and use:

proxy_pass http://172.1.0.2;
Enter fullscreen mode Exit fullscreen mode

the upstream request can retain the /blog/ portion:

172.1.0.2/blog/my-first-post
Enter fullscreen mode Exit fullscreen mode

Whereas with:

proxy_pass http://172.1.0.2/;
Enter fullscreen mode Exit fullscreen mode

Nginx can replace the matching /blog/ portion and send:

172.1.0.2/my-first-post
Enter fullscreen mode Exit fullscreen mode

That difference is extremely important.

Why?

Because I need to know what my application actually expects.

If my WordPress installation is configured to believe it lives at:

/blog
Enter fullscreen mode Exit fullscreen mode

then keeping the prefix may be what I want.

If the application is actually running at the root of the upstream server and knows nothing about /blog, I may need to strip the prefix.

This is one of the first things I check whenever I get a mysterious 404 after configuring a reverse proxy.


8. Serving an Application Under a Subpath

Here's where things get more interesting.

Routing the request is only half the problem.

Suppose my blog application is perfectly accessible when I visit:

http://172.1.0.2/
Enter fullscreen mode Exit fullscreen mode

I configure Nginx and suddenly visit:

https://mypastries.com/blog/
Enter fullscreen mode Exit fullscreen mode

The HTML loads.

Great.

Then I open the browser developer tools.

And suddenly I see:

GET /assets/main.js 404
GET /styles.css 404
GET /images/logo.png 404
Enter fullscreen mode Exit fullscreen mode

And I start wondering why Nginx has personally betrayed me.

The problem is usually not the proxy itself.

The application may be generating URLs relative to the root of the domain.

For example:

<script src="/assets/main.js"></script>
Enter fullscreen mode Exit fullscreen mode

The browser interprets that as:

mypastries.com/assets/main.js
Enter fullscreen mode Exit fullscreen mode

But I actually need:

mypastries.com/blog/assets/main.js
Enter fullscreen mode Exit fullscreen mode

Now the request goes through Nginx's / location instead of /blog/.

So the main application gets a request for an asset it doesn't have.

This is why subpath deployments need application-level awareness.

Depending on the application, I may need to configure things such as:

  • base URL

  • base path

  • asset prefix

  • public URL

  • canonical URL

  • cookie path

  • redirect URLs

The exact setting depends on the application.

The reverse proxy can route traffic, but it can't magically rewrite every assumption the application makes about where it lives.


9. Static Assets Can Be the First Sign Something Is Wrong

This is worth checking whenever a proxied application partially loads.

If the page looks broken, open DevTools β†’ Network and look for:

404
403
301
302
Enter fullscreen mode Exit fullscreen mode

especially for:

.js
.css
.png
.svg
.webp
fonts
API requests
Enter fullscreen mode Exit fullscreen mode

For example, if I see:

/blog/                    200
/blog/article             200
/assets/app.js            404
/assets/app.css           404
Enter fullscreen mode Exit fullscreen mode

that's a pretty good indication that the application doesn't understand that it is being served under /blog.

The proxy might be doing exactly what I told it to do.

The application simply doesn't know where it lives.


10. Redirects Can Also Break

Another fun one.

Suppose the application receives:

/blog/login
Enter fullscreen mode Exit fullscreen mode

and decides the user isn't authenticated.

It might respond with:

Location: /login
Enter fullscreen mode Exit fullscreen mode

The browser then goes to:

mypastries.com/login
Enter fullscreen mode Exit fullscreen mode

instead of:

mypastries.com/blog/login
Enter fullscreen mode Exit fullscreen mode

And congratulations, we're back on the main website.

This is why reverse-proxy deployments often require coordination between:

Nginx configuration + application configuration.

The proxy knows the external path.

The application needs to know that it is effectively living under that path.


11. Cookies and Sessions

Cookies are another thing I check when putting an application behind a path.

For example, an application may set:

Set-Cookie: session=abc123; Path=/
Enter fullscreen mode Exit fullscreen mode

That cookie is available across the entire domain.

Sometimes that's perfectly fine.

Sometimes I specifically want the cookie scoped to:

/blog
Enter fullscreen mode Exit fullscreen mode

depending on the application and architecture.

Authentication can become especially interesting when the main application and the proxied application both use cookies, sessions, or authentication middleware.

So if the application works perfectly on its own domain but login suddenly behaves strangely behind /blog, cookies and redirects are two of the first places I'd investigate.


12. WebSockets and Other Special Cases

Normal HTTP requests are usually straightforward.

But some applications also rely on:

  • WebSockets

  • Server-Sent Events

  • streaming responses

  • long-running connections

For WebSockets, for example, Nginx may need the appropriate upgrade headers:

location /blog/ {
    proxy_pass http://172.1.0.2;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    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_set_header X-Forwarded-Proto $scheme;
}
Enter fullscreen mode Exit fullscreen mode

Whether you need this depends entirely on what the upstream application is doing.

I wouldn't blindly add every possible Nginx directive I find on the internet.

Understand what the application needs first.


13. A More Production-Friendly Configuration

Once the basic routing works, I would normally move toward something closer to this:

server {
    listen 80;
    server_name mypastries.com;

    location / {
        proxy_pass http://172.1.0.1;

        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_set_header X-Forwarded-Proto $scheme;
    }

    location /blog/ {
        proxy_pass http://172.1.0.2;

        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_set_header X-Forwarded-Proto $scheme;
    }
}
Enter fullscreen mode Exit fullscreen mode

From here, I can add HTTPS, access/error logging, timeouts, buffering configuration, caching, rate limiting, health checks, and other production requirements depending on the application.

But I prefer getting the routing correct before turning the Nginx configuration into a 200-line configuration file that nobody wants to touch.


14. How I Think About the Request Flow

Whenever I'm debugging a reverse proxy, I find it easier to stop looking at the Nginx configuration for a moment and trace the request.

Suppose the user requests:

https://mypastries.com/blog/recipes/croissant
Enter fullscreen mode Exit fullscreen mode

The flow is roughly:

Step 1 β€” DNS

The domain resolves to the server running Nginx.

mypastries.com
       ↓
Nginx Server
Enter fullscreen mode Exit fullscreen mode

Step 2 β€” Client sends HTTP request

The browser sends something like:

GET /blog/recipes/croissant HTTP/1.1
Host: mypastries.com
Enter fullscreen mode Exit fullscreen mode

Step 3 β€” Nginx matches the request

Nginx sees:

/blog/recipes/croissant
Enter fullscreen mode Exit fullscreen mode

and matches it against:

location /blog/
Enter fullscreen mode Exit fullscreen mode

Step 4 β€” Nginx proxies the request

Nginx forwards the request to:

172.1.0.2
Enter fullscreen mode Exit fullscreen mode

Depending on the proxy_pass configuration, the upstream URI may be:

/blog/recipes/croissant
Enter fullscreen mode Exit fullscreen mode

or:

/recipes/croissant
Enter fullscreen mode Exit fullscreen mode

Step 5 β€” Upstream generates the response

The blog server processes the request and returns HTML, headers, cookies, etc.

Step 6 β€” Nginx returns the response

Nginx sends the response back to the browser.

The browser still sees:

https://mypastries.com/blog/recipes/croissant
Enter fullscreen mode Exit fullscreen mode

It doesn't need to know that the content came from:

172.1.0.2
Enter fullscreen mode Exit fullscreen mode

And that's essentially the whole trick.


15. Common Problems I Would Check First

When this setup doesn't work, I wouldn't immediately start randomly changing Nginx directives.

I'd go through the request systematically.

The domain doesn't work

Check:

DNS
↓
Server IP
↓
Nginx running?
↓
Port 80/443 open?
↓
Correct server_name?
Enter fullscreen mode Exit fullscreen mode

The main website works but /blog returns 404

Check:

location matching
↓
proxy_pass
↓
upstream application
↓
whether the upstream expects /blog or /
Enter fullscreen mode Exit fullscreen mode

HTML works but CSS/JS doesn't

Check:

Generated asset URLs
↓
Application base path
↓
Nginx location matching
Enter fullscreen mode Exit fullscreen mode

Login works but redirects to the wrong place

Check:

Location headers
↓
Application base URL
↓
proxy_redirect
↓
cookie configuration
Enter fullscreen mode Exit fullscreen mode

The application thinks everyone has the same IP

Check:

X-Real-IP
X-Forwarded-For
Enter fullscreen mode Exit fullscreen mode

WebSockets don't work

Check:

HTTP/1.1
Upgrade
Connection
Enter fullscreen mode Exit fullscreen mode

This approach saves a lot of time because you're debugging the request flow, not just throwing configuration directives at the problem.


16. Path-Based Routing vs Subdomains

At this point, it's worth asking:

Why not just use blog.mypastries.com?

Honestly, sometimes that's the better solution.

Subdomains are simpler when the application is completely independent and doesn't need to pretend that it lives inside the main website.

For example:

www.mypastries.com
blog.mypastries.com
admin.mypastries.com
api.mypastries.com
Enter fullscreen mode Exit fullscreen mode

can be a perfectly sensible architecture.

Path-based routing becomes particularly interesting when I want the external experience to look like one unified application:

mypastries.com/
mypastries.com/blog/
mypastries.com/docs/
mypastries.com/app/
Enter fullscreen mode Exit fullscreen mode

It can also be useful when I want different technologies, deployments, or teams to own different sections of the same public-facing domain.

The important thing is not to treat one approach as universally better.

Choose the URL architecture based on how the applications actually need to work.


17. The Bigger Picture

The pastry blog was just a convenient example.

The same pattern can be used to put completely different applications behind a single domain:

                        example.com
                             β”‚
                             β–Ό
                           Nginx
                             β”‚
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚             β”‚       β”‚           β”‚             β”‚
       β–Ό             β–Ό       β–Ό           β–Ό             β–Ό
      /              /app    /api        /admin        /docs
       β”‚              β”‚       β”‚           β”‚             β”‚
       β–Ό              β–Ό       β–Ό           β–Ό             β–Ό
   Website         App     Backend     Admin Panel    Docs
Enter fullscreen mode Exit fullscreen mode

The applications don't even need to use the same technology.

I could have:

/       β†’ Next.js
/blog   β†’ WordPress
/api    β†’ Node.js
/admin  β†’ React
/docs   β†’ another static site
Enter fullscreen mode Exit fullscreen mode

And Nginx can sit in front of all of them.

That's the real value of path-based reverse proxying.

I'm not necessarily creating one giant application.

I'm creating one public entry point for multiple independent applications.


18. Why Not Use an API Gateway or Cloud Service?

At this point, you might be thinking:

"Why configure Nginx myself? Can't I just use an API Gateway or some managed cloud service?"

Of course you can. In fact, depending on the scale and architecture, you probably should.

Services like AWS Application Load Balancer, API Gateway, CloudFront, or similar managed solutions can handle routing, TLS, health checks, scaling, monitoring, and high availability without you having to maintain the proxy server yourself.

But for our use case, we're simply doing:

mypastries.com/
      ↓
   Server A

mypastries.com/blog/
      ↓
   Server B
Enter fullscreen mode Exit fullscreen mode

If I already have a server running Nginx, adding a managed service just for this can introduce unnecessary infrastructure and cost.

So my general rule is:

Use Nginx when the routing is simple and you want direct control. Use a managed service when you need scalability, high availability, cloud integrations, or don't want to maintain the infrastructure yourself.

And one small clarification: an API Gateway isn't necessarily the natural choice just because we're routing requests. API gateways are primarily designed around API management, while a reverse proxy or load balancer is often a better fit for routing websites and applications.

The goal isn't to use the fanciest infrastructure available.

It's to use the simplest infrastructure that solves the problem reliably.

Conclusion

Reverse proxying looks complicated when you first encounter a giant Nginx configuration with twenty location blocks and enough directives to make you reconsider your career.

But the fundamental idea is actually pretty simple:

Client
  ↓
Nginx
  ↓
Choose upstream based on request
  ↓
Backend application
Enter fullscreen mode Exit fullscreen mode

With path-based routing, that decision can be based on the URL:

/       β†’ Server A
/blog   β†’ Server B
/api    β†’ Server C
/admin  β†’ Server D
Enter fullscreen mode Exit fullscreen mode

The important part is remembering that routing the request and making the application work under that route are two different problems.

Nginx can happily forward /blog/my-post to your blog server.

It can't automatically fix an application that still thinks it lives at /.

That's where most of the interesting problems beginβ€”asset paths, redirects, cookies, WebSockets, canonical URLs, and application-specific base paths.

Once you understand that distinction, reverse proxy configuration stops feeling like mysterious DevOps wizardry and starts looking like what it really is:

a traffic-routing problem sitting between your users and your applications.


I hope you found this helpful! If you have any feedback or suggestions for improvement, please feel free to reach out. I'm always looking to learn and improve, and your input is invaluable. If you have read it till now, thank you so much for reading!, please leave your comments if any ✌️

Don't forget to bookmark this blog for the future πŸ“Œ

Connect with the author:

Top comments (2)

Collapse
 
raknaos profile image
Raknaos

The redirects bullet is where path-based routing usually dies. You get the proxy to strip the prefix, the app answers Location: /login, and the browser is instantly off the mount point β€” and the fix is not in nginx at all, it's base-path config in the app. Same story with the cookie Path=, which I've watched break sessions only on the path-mounted app while the one at the root worked fine.

Which combination did you settle on: proxy passing X-Forwarded-Prefix and the framework trusting it, or rewriting Location and Set-Cookie on the way out? The first is much cleaner when the app supports it; the second is the only option when it doesn't, and it quietly hides bugs later.

Collapse
 
solitrix02 profile image
Sanchit Bajaj

Hey, thanks for pointing that out! I completely missed mentioning this. πŸ˜…

In my setup, I went with the X-Forwarded-Prefix approach and configured the application to trust it. It worked better for my use case and keeps the proxy configuration cleaner.