I'm trying to make my Nginx a bit more dry, as it's acting as a reverse proxy for nearly 20 servers. Here's what I'm trying to do, all the hostnames and stuff are changed/examples:
map $http_host $backend {
baz.mydomain.com hostname1:8080;
foo.mydomain.com 192.168.1.10:8081;
bar.mydomain.com hostname2:1234;
ham.mydomain.com hostname2:5678;
}
server {
listen 443 ssl http2;
server_name .mydomain.com;
ssl_certificate /usr/share/nginx/certs/mydomain.com.pem;
ssl_certificate_key /usr/share/nginx/certs/mydomain.com.key;
location / {
proxy_redirect http:// https://;
proxy_pass http://$backend;
}
}
The problem is that no matter what, this will always give a bad gateway error. I've tried a few variations and moving things around, with and without the wildcard server_name, with $host instead of $http_host but so far I can't get it working. Am I even going about this the right way? I'd really prefer not to have almost 20 separate virtual server entries in my config.
There isn't a whole lot of help in the nginx documentation about using map like this, and not a lot online except for one really old post that briefly mentioned something similar here: https://serverfault.com/questions/342309/how-to-write-a-dry-modular-nginx-conf-reverse-proxy-with-named-locations
I got it figured out. The issue was that it didn't like having hostnames in the list. The hostnames are needed as all these addresses are allocated dynamically. This was solved with the upstream directive as follows:
upstream bazhost {server hostname1:8080;}
upstream foohost {server 192.168.1.10:8081;}
upstream barhost {server hostname2:1234;}
upstream hamhost {server hostname2:5678;}
map $http_host $backend {
baz.mydomain.com bazhost;
foo.mydomain.com foohost;
bar.mydomain.com barhost;
ham.mydomain.com hamhost;
}
server {
listen 443 ssl http2;
server_name .mydomain.com;
ssl_certificate /usr/share/nginx/certs/mydomain.com.pem;
ssl_certificate_key /usr/share/nginx/certs/mydomain.com.key;
location / {
proxy_redirect http:// https://;
proxy_pass http://$backend;
}
}