Search code examples
marathontraefik

Using a frontend port that is different from the backend port


I have a traefik instance in front of a service. The service runs on port 9000. However I would like port :8000 to proxy the request to this service. Both run in marathon.

I tried using traefik.port label however it seems to be assuming that the backend is running on 8000 too when I do this judging from the backend block at :8000/dashboard.

I also tried other solutions such as

traefik.frontend.rule=Host:traefikhost:8000 with no success

The docs are really unclear on this case


Solution

  • You need to use traefik.port to define the port of your backend. In your case it should be traefik.port=9000.

    By default Traefik will listen on port 80, as you want it to listen on another port you need to define the address for entryPoints, like --entryPoints='Name:http Address::8000', in this example it will listen on port 8000.

    I will give you an example using docker, then you can make a parallel with marathon.

    Run Traefik to listen on port 8000:

    docker service create \
        --name traefik \
        --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
        --network traefik-net \
        --publish 8080:8080 \
        --publish 8000:8000 \
        traefik \
            --entryPoints="Name:http Address::8000" \
            --defaultentrypoints="http" \
            --checknewversion=false \
            --docker \
            --docker.swarmmode \
            --docker.domain=mydomain.com \
            --docker.watch \
            --docker.exposedbydefault=false \
            --web \
            --loglevel=DEBUG
    

    Backend listening on port 9000:

    docker service create \
        --name myweb \
        --mount type=bind,source=$PWD/httpd.conf,target=/usr/local/apache2/conf/httpd.conf \
        --label traefik.port=9000 \
        --label traefik.enable=true \
        --network traefik-net \
        httpd
    

    Test it, check Traefik api:

    $ curl -s "http://localhost:8080/api" | jq .
    {
      "docker": {
        "backends": {
          "backend-myweb": {
            "servers": {
              "server-myweb-1": {
                "url": "http://10.0.0.5:9000",
                "weight": 0
              }
            },
            "loadBalancer": {
              "method": "wrr"
            }
          }
        },
        "frontends": {
          "frontend-Host-myweb-mydomain-com": {
            "entryPoints": [
              "http"
            ],
            "backend": "backend-myweb",
            "routes": {
              "route-frontend-Host-myweb-mydomain-com": {
                "rule": "Host:myweb.mydomain.com"
              }
            },
            "passHostHeader": true,
            "priority": 0,
            "basicAuth": []
          }
        }
      }
    }
    

    Now request your backend service:

    $ curl -H "Host: myweb.mydomain.com" "http://localhost:8000/"
    <html><body><h1>It works!</h1></body></html>