45

I am running nginx as reverse proxy for the site example.com to loadbalance a ruby application running in backend server. I have the following proxy_set_header field in nginx which will pass host headers to backend ruby. This is required by ruby app to identify the subdomain names.

location / {
    proxy_pass http://rubyapp.com;
    proxy_set_header Host $http_host;
}

Now I want to create an alias beta.example.com, but the host header passed to backend should still be www.example.com otherwise the ruby application will reject the requests. So I want something similar to below inside location directive.

if ($http_host = "beta.example.com") {
    proxy_pass http://rubyapp.com;
    proxy_set_header Host www.example.com;
}

What is the best way to do this?

1
  • 4
    This is more appropriate for Server Fault. Commented Jan 16, 2013 at 6:46

4 Answers 4

44

You cannot use proxy_pass in if block, so I suggest to do something like this before setting proxy header:

set $my_host $http_host;
if ($http_host = "beta.example.com") {
  set $my_host "www.example.com";
}

And now you can just use proxy_pass and proxy_set_header without if block:

location / {
  proxy_pass http://rubyapp.com;
  proxy_set_header Host $my_host;
}
Sign up to request clarification or add additional context in comments.

2 Comments

In what scope should I write the if statement ? server or location ?
It should be mentioned, that this directive can be used only once for the header on the current level due to the documentation. > proxy_set_header Allows redefining or appending fields to the request header passed to the proxied server. ... directives are inherited from the previous configuration level if and only if there are no proxy_set_header directives defined on the current level
35

map is better than set + if.

map $http_host $served_host {
    default $http_host;
    beta.example.com www.example.com;
}

server {
    [...]

    location / {
        proxy_pass http://rubyapp.com;
        proxy_set_header Host $served_host;
    }
}

2 Comments

In nginx docs, it's mentioned that set and if are fine if not in the location, but within the server. However, map is also a good alternative.
Could you source the docs you mention? I never read that. Moreover, tickets for nginx involving if often points out trouble related to their use. For instance: #1383. Advice to avoid set & if still stands.
5

Just a small tip. Sometimes you may need to use X-Forwarded-Host instead of Host header. That was my case where Host header worked but only for standard HTTP port 80. If the app was exposed on non-standard port, then this port was lost when the app generated redirects. So finally what worked for me was:

proxy_set_header X-Forwarded-Host $http_host;

Comments

4

I was trying to solve the same situation, but with uwsgi_pass.

After some research, I figured out that, in this scenario, it's required to:

uwsgi_param HTTP_HOST $my_host;

Hope it helps someone else.

1 Comment

This is exactly what I was looking for, thanks so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.