Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure Nginx to try two upstreams before 404ing?

Given an Nginx configuration roughly like this:

upstream A {
    server aa:8080;
}

upstream B {
    server bb:8080;
}

server {
  listen 80;

  location @backendA {
    proxy_pass http://A/;
  }

  location @backendB {
    proxy_pass http://B/;
  }

  location / {
    # This doesn't work. :)
    try_files @backendA @backendB =404;
  }
}

Basically, I would like Nginx to try upstream A, and if A returns a 404, then try upstream B instead, and failing that, return a 404 to the client. try_files does this for filesystem locations, then can fall back to a named location, but it doesn't work for multiple named locations. Is there something that will work?

Background: I have a Django web application (upstream A) and an Apache/Wordpress instance (upstream B) that I would like to coexist in the same URL namespace for simpler Wordpress URLs: mysite.com/hello-world/ instead of mysite.com/blog/hello-world/.

I could duplicate my Django URLs in the Nginx locations and use wordpress as a catch-all:

location /something-django-handles/ {
  proxy_pass http://A/;
}

location /something-else-django-handles/ {
  proxy_pass http://A/;
}

location / {
  proxy_pass http://B/;
}

But this violates the DRY principle, so I'd like to avoid it if possible. :) Is there a solution?

like image 865
David Eyk Avatar asked Feb 04 '15 21:02

David Eyk


1 Answers

After further googling, I came upon this solution:

location / {
    # Send 404s to B
    error_page 404 = @backendB;
    proxy_intercept_errors on;
    log_not_found  off;

    # Try the proxy like normal
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_pass http://A;
}

location @backendB {
    # If A didn't work, let's try B.
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_pass http://B;

    # Any 404s here are handled normally.
}
like image 102
David Eyk Avatar answered Oct 26 '22 13:10

David Eyk