Subdomains for ports on same (Ubuntu) server with nginx reverse proxy

I have a firewall that blocks pretty much anything except port 80. Because of this, I just spent two days trying to set up a reverse proxy on my new server at http://cadence.singles.

Really dumbed down, a reverse proxy handles all traffic on the same port (80) and directs it within its network, before serving the response as if it did all the work.

I needed this in order to let select subdomains point to applications on other ports (but on the same server) behind the firewall. Specifically, I wanted:

As a complete newbie to HTTP servers, I started out with apache2/httpd and spent hours trying to understand how the configuration worked. When I finally took the entire server down, I decided to migrate to nginx. Best choice ever.

Here’s what I did to do what I did.

First off, configuring a reverse proxy does not magically configure the subdomains to point to your server’s IP. This took me quite a lot of time to understand. I host my servers on Linode, so I headed over there and configured it through their DNS manager.

In fact, I set up a “catch-all” subdomain (*) to point to my server’s IP address, basically saying that “no matter what comes before “.cadence.singles”, I want it directed here”. I could (and should, probably) have configured each one individually, but I honestly couldn’t be arsed. My configuration ended up like this (the IP pointing to my server):

DNS config @ Linode

DNS config @ Linode

Note: The configuration probably takes some time (we’re talking minutes, maybe even hours) to take effect. Then there’s caching and all that. Also note that the blank hostname points to no subdomain, that is, just http://cadence.singles. I messed that up.

Second, I installed nginx on my server:

  1. sudo apt-get install nginx

Third, I started the server and made sure it worked as intended, even with subdomains:

  1. sudo service nginx start (or, if you’re old school: sudo /etc/init.d/nginx start)
  2. http://cadence.singles (port 80 is the default)
  3. http://randomsubdomain.cadence.singles

Both 2. and 3. showed me the same page telling me it worked, so this was where the configuration bit came in.

Fourth: In the nginx default configuration directory (/etc/nginx/conf.d), I created a file called servers.conf. This file configures each server I wanted a specific subdomain for. I needed root access all the way. By the way, I like vim.

  1. sudo vim /etc/nginx/conf.d/servers.conf

I started out with Jenkins (on port 7070). I declared a server named ci.cadence.singles, which listens on port 80:

server {
        listen 80;
        server_name ci.cadence.singles;
}

Then, I told it what I wanted it to do inside the server block. The only thing to really note is the proxy_pass address. Everything else can easily be the same in any configuration. The final configuration (/etc/nginx/conf.d/servers.conf) ended up like this:

server {
        listen 80;
        server_name ci.cadence.singles;

        location / {
                proxy_pass http://localhost:7070;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_connect_timeout 150;
                proxy_send_timeout 100;
                proxy_read_timeout 100;
                proxy_buffers 4 32k;
                client_max_body_size 8m;
                client_body_buffer_size 128k;
        }
}

FIfth, I restarted nginx, and and it just worked.

  1. sudo service nginx restart
  2. http://ci.cadence.singles

Sixth, I added the Node.js server to servers.conf by declaring a second server. I’m lazy, so I really just copied the previous block and changed the server_name and proxy_pass lines. The final file (my running config) looks like this:

server {
        listen 80;
        server_name ci.cadence.singles;
        location / {
                proxy_pass http://localhost:7070;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_connect_timeout 150;
                proxy_send_timeout 100;
                proxy_read_timeout 100;
                proxy_buffers 4 32k;
                client_max_body_size 8m;
                client_body_buffer_size 128k;
        }
}
server {
        listen 80;
        server_name node.cadence.singles;

        location / {
                proxy_pass http://localhost:3000;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_connect_timeout 150;
                proxy_send_timeout 100;
                proxy_read_timeout 100;
                proxy_buffers 4 32k;
                client_max_body_size 8m;
                client_body_buffer_size 128k;
        }
}

Then I restarted nginx again, and I was good to go.

  1. sudo service nginx restart
  2. http://ci.cadence.singles
  3. http://node.cadence.singles

PS: My configuration is likely to change, so I do not guarantee that these links actually work!

15 thoughts on “Subdomains for ports on same (Ubuntu) server with nginx reverse proxy

Was anything unclear, or do you have anything to add?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s