Issue (Gateway Timeout) when using Traefik and exposing port with Docker

Hi :slight_smile: !

I don't really know if it's an issue or it's the way it suppose to be but, I quite don't understand why exposing a port via Docker and a routing in Traefik make the service unreachable, with a gateway timeout error.

Here my docker compose :

services:
  ghost:
    ports:
      - 8087:2368
    image: ghost
    deploy:
      labels:
        - traefik.enable=true
        - traefik.http.services.ghost.loadbalancer.server.port=2368
        - traefik.http.routers.ghost.rule=Host(`ghost.fake.com`)
        - traefik.http.routers.ghost.tls=true
        - traefik.http.routers.ghost.service=ghost
    networks:
      fake:
networks:
  fake:

If I remove the "ports" part, all is working well, but can't access the container via 8087. With this config, I got from Traefik a gateway timeout.
I've seen sample of configurations that use both so, I'm a bit lost.

Here my Traefik config :

services:
  reverse-proxy:
    image: traefik:v2.3.4
    command: 
      - --api=true
      - --providers.docker
      - --providers.docker.swarmMode=true
      - --entryPoints.web-secure.address=:443
      - --entryPoints.metrics.address=:8082
      - --metrics=true
      - --metrics.prometheus=true
      - --metrics.prometheus.entryPoint=metrics
      - --log.filePath=/logs/traefik.log
      - --log.level=DEBUG
    ports:
      - "8082:8082"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      optibe:
    deploy:
      mode: global
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.traefik.rule=(Host(`${FAKE_URL}`) && PathPrefix(`/api`)) || (Host(`${FAKE_URL}`) && PathPrefix(`/dashboard`))"
        - "traefik.http.services.traefik.loadbalancer.server.port=8080"
        - "traefik.http.routers.traefik.service=api@internal"
        - "traefik.http.routers.traefik.tls=true"
        - "traefik.http.routers.traefik.middlewares=auth"
        - "traefik.http.middlewares.auth.basicauth.users=fake-user:fake-password"

Thanks for enlightening me :innocent:

Hi @FrenchTastic

I think your issue is that traefik and ghost are not on the same network, so traefik cannot reach ghost.

1 Like

Hi @cakiwi ,

I'm sorry I forgot to rename my network to "fake" in my config file they are indeed in the same network.
The service is only unavailable (Gateway Timeout) when ports are exposed and with traefik labels.

If I remove exposed ports, the service works via traefik, but cannot be reached by ports.
I need to have both.

I could not reproduce, replacing ghost image:

Curl to traefik
9:29 $ curl -ik https://ghost.fake.com --resolve ghost.fake.com:443:127.0.0.1
HTTP/2 200 
content-type: text/plain; charset=utf-8
date: Fri, 04 Dec 2020 14:29:48 GMT
content-length: 372

Hostname: 7b2fae52b816
IP: 127.0.0.1
IP: 10.0.0.73
IP: 172.19.0.3
IP: 10.0.3.7
RemoteAddr: 10.0.3.6:53926
GET / HTTP/1.1
Host: ghost.fake.com
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.0.0.2
X-Forwarded-Host: ghost.fake.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: 48f69b30e625
X-Real-Ip: 10.0.0.2

Curl to exposed port
09:29 $ curl -i http://localhost:8087
HTTP/1.1 200 OK
Date: Fri, 04 Dec 2020 14:30:06 GMT
Content-Length: 184
Content-Type: text/plain; charset=utf-8

Hostname: 7b2fae52b816
IP: 127.0.0.1
IP: 10.0.0.73
IP: 172.19.0.3
IP: 10.0.3.7
RemoteAddr: 10.0.0.2:59734
GET / HTTP/1.1
Host: localhost:8087
User-Agent: curl/7.68.0
Accept: */*
version: "3.8"

services:
  reverse-proxy:
    image: traefik:v2.3.4
    command:
      - --api=true
      - --providers.docker
      - --providers.docker.swarmMode=true
      - --entryPoints.web-secure.address=:443
      - --entryPoints.metrics.address=:8082
      - --metrics=true
      - --metrics.prometheus=true
      - --metrics.prometheus.entryPoint=metrics
      - --log.level=DEBUG
    ports:
      - "8082:8082"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - otibe
    deploy:
      mode: global
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.traefik.rule=PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
        - "traefik.http.services.traefik.loadbalancer.server.port=8080"
        - "traefik.http.routers.traefik.service=api@internal"
        - "traefik.http.routers.traefik.tls=true"
        - "traefik.http.routers.traefik.middlewares=auth"
        - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"

  ghost:
    ports:
      - 8087:2368
    image: containous/whoami
    command: --port 2368
    deploy:
      labels:
        - traefik.enable=true
        - traefik.http.services.ghost.loadbalancer.server.port=2368
        - traefik.http.routers.ghost.rule=Host(`ghost.fake.com`)
        - traefik.http.routers.ghost.tls=true
        - traefik.http.routers.ghost.service=ghost
    networks:
      - otibe

networks:
  otibe:

Ports should be enclosed in "" to avoid compose parsing as base-60 but does not matter in this case.

I managed to reproduce with another stack.

Exposing the port on the container adds it to another network ingress traefik does not know which network to send the request to.

Add the following label traefik.docker.network and specify the common network. This has to be the network name as seen in docker, not compose.

3 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.