Basil
Basil

Reputation: 443

Change Host header in nginx reverse proxy

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?

Upvotes: 44

Views: 138932

Answers (4)

Bernard Rosset
Bernard Rosset

Reputation: 4743

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;
    }
}

Upvotes: 35

ricardorover
ricardorover

Reputation: 156

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.

Upvotes: 4

TomCZ
TomCZ

Reputation: 354

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;

Upvotes: 5

Michał Kupisiński
Michał Kupisiński

Reputation: 3863

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;
}

Upvotes: 43

Related Questions