Search code examples
mongodbdockerdocker-composetraefik

I Can not connect to my mongoDb container with traefik docker


I have a server with docker. This is my docker compose file:

version: "3.3"

services:

  traefik:
    image: "traefik:v2.10"
    container_name: "traefik"
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.mongo.address=:27017"
      - "--certificatesresolvers.le.acme.tlschallenge=true"
      - "--certificatesresolvers.le.acme.email=myemail@email.com"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
    ports:
      - "443:443"
      - "8080:8080"
      - "27017:27017"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - "traefik"

  mongo:
    image: "mongo:4.4-bionic"
    restart: "always"
    container_name: "mongoDB"
    environment:
      - "MONGO_INITDB_ROOT_USERNAME=admin"
      - "MONGO_INITDB_ROOT_PASSWORD=secret"
    volumes:
      - "volDBts:/data/db"
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.mongo.rule=HostSNI(`domain1.com`)"
      - "traefik.tcp.routers.mongo.entrypoints=mongo"
      - "traefik.tcp.routers.mongo.service=mongo"
      - "traefik.tcp.services.mongo.loadbalancer.server.port=27017"
      - "traefik.tcp.routers.mongo.tls.domains[0].main=domain1.com"
    networks:
      - "traefik"

  mongo2:
    image: "mongo:4.4-bionic"
    restart: "always"
    container_name: "mongoDB2"
    environment:
      - "MONGO_INITDB_ROOT_USERNAME=admin"
      - "MONGO_INITDB_ROOT_PASSWORD=secret"
    volumes:
      - "volDBts2:/data/db"
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.mongo2.rule=HostSNI(`domain2.com`)"
      - "traefik.tcp.routers.mongo2.entrypoints=mongo"
      - "traefik.tcp.routers.mongo2.service=mongo"
      - "traefik.tcp.services.mongo2.loadbalancer.server.port=27017"
      - "traefik.tcp.routers.mongo2.tls.domains[0].main=domain2.com"
    networks:
      - "traefik"
    

volumes:
  volDBts:
  volDBts2:

networks:
  traefik:
    external: true

I can connect to mongoDB but not to mongoDB2. I'm using Mongo Compass and this is my string connection:

mongodb://admin:secret@domain1.com:27017/?tls=true&directConnection=true (I can connect) mongodb://admin:secret@domain2.com:27017/?tls=true&directConnection=true (I can not connect)

This domains domain1.com and domain2.com aren't reals but I'm using real domains, and I am sure the domains are resolving correctly to the server.

I tried to create other entrypoint in the traefik container. - "--entrypoints.mongo2.address=:27017" updating the labels in mongoDB2: - "traefik.tcp.routers.mongo2.entrypoints=mongo2" - "traefik.tcp.routers.mongo2.service=mongo2" But the traefik container fails.

I checked the logs of the traefik network and both mongodb container are in the traefik network.

I want to connect to both containers using the same port (27017) but different domain.


Solution

  • The problem is that in your mongo2 service you have the label:

    traefik.tcp.routers.mongo2.service=mongo
    

    This instruct Traefik to route traffic to the mongo service. You want:

    traefik.tcp.routers.mongo2.service=mongo2
    

    Here's the complete docker-compose.yaml that I used for testing (I removed th letsencrypt configuration, etc):

    services:
    
      traefik:
        image: "traefik:v2.10"
        command:
          - "--api.insecure=true"
          - "--providers.docker=true"
          - "--providers.docker.exposedbydefault=false"
          - "--entrypoints.websecure.address=:443"
          - "--entrypoints.mongo.address=:27017"
        ports:
          - "27017:27017"
        volumes:
          - '/var/run/docker.sock:/var/run/docker.sock'
    
      mongo:
        image: "mongo:4.4-bionic"
        environment:
          - "MONGO_INITDB_ROOT_USERNAME=admin"
          - "MONGO_INITDB_ROOT_PASSWORD=secret"
        volumes:
          - "volDBts:/data/db"
        labels:
          - "traefik.enable=true"
          - "traefik.tcp.routers.mongo.rule=HostSNI(`domain1.com`)"
          - "traefik.tcp.routers.mongo.entrypoints=mongo"
          - "traefik.tcp.routers.mongo.service=mongo"
          - "traefik.tcp.services.mongo.loadbalancer.server.port=27017"
          - "traefik.tcp.routers.mongo.tls.domains[0].main=domain1.com"
    
      mongo2:
        image: "mongo:4.4-bionic"
        environment:
          - "MONGO_INITDB_ROOT_USERNAME=admin"
          - "MONGO_INITDB_ROOT_PASSWORD=secret"
        volumes:
          - "volDBts2:/data/db"
        labels:
          - "traefik.enable=true"
          - "traefik.tcp.routers.mongo2.rule=HostSNI(`domain2.com`)"
          - "traefik.tcp.routers.mongo2.entrypoints=mongo"
          - "traefik.tcp.routers.mongo2.service=mongo2"
          - "traefik.tcp.services.mongo2.loadbalancer.server.port=27017"
          - "traefik.tcp.routers.mongo2.tls.domains[0].main=domain2.com"
    
    volumes:
      volDBts:
      volDBts2:
    

    After bringing this up, if I run:

    mongosh --tlsAllowInvalidCertificates  --tls mongodb://admin:secret@domain1.com:27017/
    

    See in the logs:

    mongo_1    | {"t":{"$date":"2023-06-30T21:27:00.957+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"172.30.0.2:53188","connectionId":1,"connectionCount":1}}
    

    And if I run:

    mongosh --tlsAllowInvalidCertificates  --tls mongodb://admin:secret@domain2.com:27017/
    

    I see in the logs:

    mongo2_1   | {"t":{"$date":"2023-06-30T21:27:19.835+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"172.30.0.2:55264","connectionId":1,"connectionCount":1}}
    

    So everything seems to be working as expected.