First, I would argue that what you have right now is the most common configuration: your reverse proxy (nginx/traefik/haproxy/etc) listens on a single address and then routing requests to appropriate backend hosts by name. Configuring a separate external ip for each domain adds a level of complexity that may not be necessary.
However, if you really want to do that, start by adding multiple ip addresses to your host. For example, on my host, I have:
$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
altname eno2
altname enp0s31f6
inet 192.168.1.200/24 brd 192.168.1.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 192.168.1.201/24 brd 192.168.1.255 scope global secondary noprefixroute eth0
valid_lft forever preferred_lft forever
inet 192.168.1.202/24 brd 192.168.1.255 scope global secondary noprefixroute eth0
valid_lft forever preferred_lft forever
inet 192.168.1.175/24 brd 192.168.1.255 scope global secondary dynamic noprefixroute eth0
valid_lft 55548sec preferred_lft 55548sec
I have a sample configuration in which I am running nginx as the frontend with two different backends (named backend1
and backend2
).
I'm going to configure nginx so that connections to 192.168.1.201
go to backend1
and connections to 192.168.1.202
go to backend2
. We do that by:
- Having nginx listen on multiple ports (one port for each backend), and then
- Publishing these ports on different ip addresses
We start with the nginx
configuration:
server {
listen 8000;
server_name localhost;
location / {
proxy_pass http://backend1/;
}
}
server {
listen 8001;
server_name localhost;
location / {
proxy_pass http://backend2/;
}
}
This maps connections on port 8000 to backend1
and connections on port 8001 to backend2
. To expose these on port 80 on different host addresses, we can create a docker-compose.yaml
like this:
services:
frontend:
image: docker.io/nginx:mainline
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
ports:
- 192.168.1.201:80:8000
- 192.168.1.202:80:8001
backend1:
image: docker.io/containous/whoami:latest
backend2:
image: docker.io/containous/whoami:latest
This means that connections to http://192.168.1.201
will get mapped to port 8000, and hence to backend1
, while connections to http://192.168.1.202
will get mapped to port 8001, and hence to backend2
.
After running docker-compose up
, I can confirm this configuration:
$ curl -s 192.168.1.201 | grep Host:
Host: backend1
$ curl -s 192.168.1.202 | grep Host:
Host: backend2