Access Postgresql instance with subdomain using traefik

Hello all,
I'm new with Traefik and need your help.

I have a self-hosted instance of PostgreSQL install in Server 1
I have Traefik service running in Server 2

I want to connect to my PostgresSQL database with a subdomain from Internet for Dev/Test Purpose.

In the application.propertises file of my project, I want to use it like this:

spring.datasource.url=jdbc:postgres://psql.mydomain.com:traefik_exposed_port/my_db

And if traefik receive this tcp request it have to send it to Server 1 throw internal IP Address and PostgreSQL instance Port

How to do it ?

Thanks

Hello @aristos

Here is an example docker-compose that will setup Postgres, pgadmin and Traefik. The Postgres container listens by the default on port 5432, I'm also setting up a TCP entrypoint and router in Traefik on the same port.

#Traefik static configuration /sandbox/configs/static/proxy-v2.yml
 api:
  dashboard: true
  debug: true

entryPoints:
  web:
    address: ":80"

  websecure:
    address: ":443"

  tcp:
    address: ":5432"

providers:
  docker: {}
  #file:
  #  filename: /dynamic.yml
  #  watch: true
version: '3'
services:
    postgres:    
      image: postgres
      labels:
        - "traefik.enable=true"
        - "traefik.tcp.routers.postgres.rule=HostSNI(`*`)"
        - "traefik.tcp.routers.postgres.entrypoints=tcp"
        - "traefik.tcp.services.postgres.loadbalancer.server.port=5432"
      environment:
        POSTGRES_USER: ${POSTGRES_USER:-postgres}
        POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
        PGDATA: /data/postgres
      volumes:
        - postgres:/data/postgres
      networks:
        - traefik

    pgadmin:
      image: dpage/pgadmin4
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.pgadmin.entrypoints=web"
        - "traefik.http.routers.pgadmin.rule=Host(`pgadmin.docker.localhost`)"
        - "traefik.http.services.pgadmin.loadbalancer.server.port=80"
      environment:
        PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4@pgadmin.org}
        PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
        PGADMIN_CONFIG_SERVER_MODE: 'False'
      volumes:
        - pgadmin:/var/lib/pgadmin
      networks:
        - traefik

    traefik:
      image: "traefik:v2.8"
      command:
        - "--log.level=DEBUG"
        - "--configfile=/traefik.yml"
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.api.entrypoints=web"
        - "traefik.http.routers.api.rule=Host(`traefik.docker.localhost`)"
        - "traefik.http.routers.api.service=api@internal"
      ports:
        - "80:80"
        - "443:443"
        - "5432:5432"
      networks:
        - traefik
      volumes:
        - /var/run/docker.sock:/var/run/docker.sock:ro
        - /sandbox/configs/static/proxy-v2.yml:/traefik.yml
        #- /sandbox/configs/file-provider.yml:/dynamic.yml

networks:
  traefik:

volumes:
    postgres:
    pgadmin:

Traefik Dashboard would be accessible at traefik.docker.localhost, given you have that alias configured in Docker.

pgadmin is at pgadmin.docker.localhost and from its own Dashboard you can setup a connection to Postgres directly, by using the address postgres or through Traefik, by using traefik as the server address this time. It works because the rule on the tcp entrypoint is set to *, so its basically redirecting everything Traefik receives on port 5432 to Postgres at port 5432.

I hope that gives you a good idea on how things can be stitched together as we have both HTTP and TCP routers configured on this example.

Alternatively if your Postgres server is an external server you might want to set it up with a static routing rule via the File provider instead of relying on Docker labels in this case. For that I left some lines commented out on the previous static + docker compose files. Here is an example for its content:

#Traefik dynamic config for the File provider /sandbox/configs/file-provider.yml
tcp:
  routers:
    postgres:
      entryPoints:
      - tcp
      service: tcp@file
      rule: HostSNI(`*`)
  services:
    tcp:
      loadBalancer:
        servers:
          - address: postgres:5432

Hello @douglasdtm ,

Thank you for your answer.

Indeed, my Postgres Server is an external server and it's not install in a docker container. It's install directly on my server host (VPC).

Let me give a try of Traefik dynamic suggested file and I'll be back to tell if it's Ok.

I have two more questions, but let first finished with this one.

Thanks

Hello @douglasdtm ,

It's not work with dynamic config, but it's work when traefik and postgres service are in the same docker compose file. Now I can connect my Quarkus App to Dev database through Traefik. Thanks a lot.

My other questions :

  • How can I use Traefik to revese proxy Apache Tomcat 10 ? (Traefik and Apache Tomcat are in the same VPC)
  • How can I use Traefik to reverse proxy Apache HTTP Server 2.4 (Apache HTTP Server is in different VM)

Can I have samples like previous ?

Thank you.

Hi @aristos,

The issue when not running on the same compose is probably because either the network is not reachable or the address is not resolvable. When you apply a dynamic configuration with the File provider you assume Traefik can reach directly to the addresses specified under servers:, in my example you would assume postgres resolved to a network address in the same network as Traefik.

As for Apache Tomcat and HTTP I don't have any ready examples at hand but the structure should be pretty much the same as for postgres, except maybe you want HTTP routers instead of TCP.

If anyone else have examples on this please follow up as it would be really helpful here and also on this other post :slight_smile: