Nginx Proxying to Multiple IP Addresses for CMS' Website Preview
- by Matthew Borgman
First-time poster, so bear with me.
I'm relatively new to Nginx, but have managed to figure out what I've needed... until now.
Nginx v1.0.15 is proxying to PHP-FPM v.5.3.10, which is listening at http://127.0.0.1:9000. [Knock on wood] everything has been running smoothly in terms of hosting our CMS and many websites.
Now, we've developed our CMS and configured Nginx such that each supported website has a preview URL (e.g. http://[WebsiteID].ourcms.com/) where the site can be, you guessed it, previewed in those situations where DNS doesn't yet resolve to our server, etc.
Specifically, we use Nginx's Map module (http://wiki.nginx.org/HttpMapModule) and a regular expression in the server_name of the CMS' server{ } block to 1) lookup a website's primary domain name from its preview URL and then 2) forward the request to the "matched" primary domain.
The corresponding Nginx configuration:
map $host $h {
123.ourcms.com www.example1.com;
456.ourcms.com www.example2.com;
789.ourcms.com www.example3.com;
}
and
server {
listen [OurCMSIPAddress]:80;
listen [OurCMSIPAddress]:443 ssl;
root /var/www/ourcms.com;
server_name ~^(.*)\.ourcms\.com$;
ssl_certificate /etc/nginx/conf.d/ourcms.com.chained.crt;
ssl_certificate_key /etc/nginx/conf.d/ourcms.com.key;
location / {
proxy_pass http://127.0.0.1/;
proxy_set_header Host $h;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
(Note: I do realize that the regex in the server_name should be "tighter" for security reasons and match only the format of the website ID (i.e. a UUID in our case).)
This configuration works for 99% of our sites... except those that have a dedicated IP address for an installed SSL certificate. A "502 Bad Gateway" is returned for these and I'm unsure as to why.
This is how I think the current configuration works for any requests that match the regex (e.g. http://123.ourcms.com/):
Nginx looks up the website's primary domain from the mapping, and
as a result of the proxy_pass http://127.0.0.1 directive, passes the request back to Nginx itself, which
since the proxied request has a hostname corresponding to the website's primary domain name, via the proxy_set_header Host $h directive, Nginx handles the request as if it was as direct request for that hostname.
Please correct me if I'm wrong in this understanding.
Should I be proxying to those website's dedicated IP addresses? I tried this, but it didn't seem to work? Is there a setting in the Proxy module that I'm missing?
Thanks for the help.
MB