Routing traffic to servers on specific ports based on host header using HETZNER and nginx

Routing traffic to servers on specific ports based on host header using HETZNER and nginx


We are in the middle of migrating from AWS to Hetzner, and if you have ever been on these major migration projects, you’d know the challenges that come with it firsthand. In this post, I am going to talk about a very specific problem we were facing on Hetzner and how we overcame that.

So we have been using AWS for over 6 years and finally took the plunge to migrate from AWS (I wrote about it in this post as to why).

We host dedicated instances of our platform for our customers at Sopact, including the database and the web application. The web application is served from a kubernetes pod and each application runs on a different port. For example, myorg.sopact.com would be hosted on something like http://kubernetes_server:56035. and myorg2.sopact.com would be hosted on http://kubernetes_server:6342. As you might already know, the default port for websites is port 80 (http) and 443 (https), so how can we work with a different port?

This is where AWS ALB provides you an excellent feature where it lets you route traffic to specific servers on specific ports based on the host. Considering the same example,

If someone were to type myorg.sopact.com, AWS allows you to match this host and forwards the traffic to http://kubernetes_server:56035. Why is this important?

It is important as it allows you to host multiple customer instances on a single server. It is massive cost saving (not on AWS though 🙂 ).

So, now we want to migrate over to HETZNER and obviously we expect the same feature to be available on its load balancer. Unfortunately, this is not the case. HETZNER doesn’t allow you to match the host and forward requests to particular servers on a particular port. One way to overcome this is that you literally create dedicated servers for every customer. This would work but would be very expensive. By the way, even with dedicated server for every customer HETZNER still turns out cheaper than AWS. Yes you read that right.

Repeat after me. AWS is expensive as hell. It is a rip off.

To overcome the limitation that I just described, there is a neat workaround. Thanks to nginx.

We use HETZNER load balancer that routes traffic to an nginx server on port 80. The nginx server then matches the host and forwards requests to appropriate server on appropriate ports. This is amazing as it lets us achieve the same results and at a much lower cost.

This is the nginx configuration if you were wondering as to how?

server {
        listen 80;
        server_name myorg1.yourdomain.com;

        location / {
            proxy_pass http://your_ip:30565;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }

    server {
        listen 80;
        server_name myorg2.yourdomain.com;

        location / {
            proxy_pass http://your_ip:32173;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }

All requests to myorg1.yourdomain.com is forwarded to http://your_ip:30565. This is so cool and such a relief!

Thanks to open-source and a big thanks to the tech community!

Madhukar Prabhakara Avatar