TCP Routing to two database containers

Hi, I am trying to use Traefik to route into two different database (postgres) containers using names so that I don't have to connect to them using made up ports. So instead of having...

myserver.com:5432 (db1)
myserver.com:5433 (db2)

I want to be able to do....

db1.myserver.com
db2.myserver.com

From reading the documentation, I believe that this would be accomplished using the TCP load balancer. But because I run over plain TCP, HostSNI has to be *, so traefik does not know which router to forward to. here is my example config:

docker-compose.yml

  traefik:
    image: traefik:v2.8.3
    container_name: traefik
    ports:
      - 5432:5432
    volumes:
      - /home/user/traefik/traefik.toml:/etc/traefik/traefik.toml:ro
      - /home/user/traefik/dynamic.toml:/etc/traefik/dynamic.toml:ro
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      traefik_network:
    restart: unless-stopped

    db1:
        image: postgres:14
        ports:
            - 5432
        volumes:
            - /home/user/db1:/var/lib/postgresql/data
        labels:
            - "traefik.enable=true"
            - "traefik.tcp.routers.db1.entrypoints=db"
            - "traefik.tcp.routers.db1.rule=HostSNI(`*`)"
            - "traefik.tcp.routers.db1.service=db1"
            - "traefik.tcp.routers.db1.tls=false"
            - "traefik.tcp.services.db1.loadbalancer.server.port=5432"
        networks:
            traefik_network:

    db2:
        image: postgres:14
        ports:
            - 5432
        volumes:
            - /home/user/db2:/var/lib/postgresql/data
        labels:
            - "traefik.enable=true"
            - "traefik.tcp.routers.db2.entrypoints=db"
            - "traefik.tcp.routers.db2.rule=HostSNI(`*`)"
            - "traefik.tcp.routers.db2.service=db2"
            - "traefik.tcp.routers.db2.tls=false"
            - "traefik.tcp.services.db2.loadbalancer.server.port=5432"
        networks:
            traefik_network:

networks:
  traefik_network:
    ipam:
      driver: default

traefik.toml:

[entrypoints]
  [entrypoints.db]
    address = ":5432/tcp"

Obviously, I have configured my DNS server to resolve *.myserver.com to he same host as myserver.com

Let me know if what I'm trying to do is possible, happy to try any alternative methods too.

1 Like

I'm trying to do the same but without much success. I think in v3 you should be able to specify a different name in HostSNI. But in 2.10 I cannot get it to work.

To route by domain on the same port you need to have http (Host()) or TLS (HostSNI()). For TLS, Traefik needs access to the certs or has self created them with LetsEncrypt to read the domain.

The following main scenarios are possible:

  1. TLS is done between client and target service, the target service creates is own TLS cert, Traefik does not know it. Then you can only route via HostSNI(`*`) and need a different port for every service.
  2. TLS is only done between client and Traefik, internally data is forwarded unencrypted. Then traffic can generate a cert with LetsEncrypt and route by domain easily.

There are further options, you can buy TLS certificates and use those with Traefik and your target service, then encryption goes all the way.

Or you can use different certificates between clients and Traefik and Traefik and target service. But it requires more configuration.

1 Like