Search code examples
dockerdocker-composetraefik

How to use traefik segments to route request to the right service on the right port of the same container


I have a docker container that has 2 ports exposed, each for a different web service. One is an API, the other is a simple web page with documentation.

I have tried to understand Traefik's doc. Looks like I need to use segments and I am failing miserably.

I want

This is what I have now, which works but only serves port 4000

  my-service:
    image: myregistry.com:5005/my-service:latest
    container_name: my-service
    labels:
      - traefik.http.routers.my-service-router.tls=true
      - traefik.http.routers.my-service-router.entrypoints=secure
      - traefik.http.routers.my-services-router.rule=Host(`www.mydomain.net`)
    networks:
      - internal

and I tried segments as follow

  my-service:
    image: myregistry.com:5005/my-service:latest
    container_name: my-service
    expose:
      - 4000 # my API
      - 3000 # my doc
    labels:
      # segment myapi
      - traefik.myapi.port=4000
      - traefik.myapi.http.routers.my-service-router.tls=true
      - traefik.myapi.http.routers.my-service-router.entrypoints=secure
      - traefik.myapi.http.routers.my-services-router.rule=Host(`api.mydomain.net`)
      # segment mydoc
      - traefik.mydoc.port=3000
      - traefik.mydoc.http.routers.my-service-router.tls=true
      - traefik.mydoc.http.routers.my-service-router.entrypoints=secure
      - traefik.mydoc.http.routers.my-services-router.rule=Host(`doc.mydomain.net`)
    networks:
      - internal

but it's wrong isn't it? so I tried different accordingly to the doc...

  my-service:
    image: myregistry.com:5005/my-service:latest
    container_name: my-service
    expose:
      - 4000 # my service
      - 3000 # my other service
    labels:
      # segment myapi
      - traefik.myapi.port=4000
      - traefik.myapi.frontend.entrypoints=secure
      - traefik.myapi.frontend.rule=Host(`api.mydomain.net`)
      # segment mydoc
      - traefik.mydoc.port=3000
      - traefik.mydoc.frontend.entrypoints=secure
      - traefik.mydoc.frontend.rule=Host(`doc.mydomain.net`)
    networks:
      - internal

I am not understanding the doc, so any pointers would be welcome.


Solution

  • I'm pretty sure that "mydoc" and "myapi" shouldn't be there:

    my-service:
      image: myregistry.com:5005/my-service:latest
      container_name: my-service
      expose:
        - 4000 # my service
        - 3000 # my other service
      labels:
        # segment myapi
        - traefik.http.services.myapi.loadbalancer.server.port=4000
        - traefik.http.routers.myapi.entrypoints=secure
        - traefik.http.routers.myapi.rule=Host(`api.mydomain.net`)
        - traefik.http.routers.myapi.service=myapi
        # segment mydoc
        - traefik.http.services.mydoc.loadbalancer.server.port=3000
        - traefik.http.routers.mydoc.entrypoints=secure
        - traefik.http.routers.mydoc.rule=Host(`adoci.mydomain.net`)
        - traefik.http.routers.mydoc.service=mydoc
      networks:
        - internal
    

    Also check that the traefik container is in the internal network too.