Forward request to different machine

Hi! Im trying to setup traefik to forward request from machine 1 to machine 2. From machine 1 I am able to curl the webserver on machine 2, but if I try to curl the request via traefik it doesn't work. Here my setup:

Docker compose:

services:
  socket-proxy:
    image: tecnativa/docker-socket-proxy
    container_name: socket-proxy
    restart: unless-stopped
    networks:
      - proxy
    environment:
      - CONTAINERS=1
      - NETWORKS=1
      - SERVICES=1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  traefik:
    image: traefik:v2.6
    container_name: traefik
    command:
      - '--log.level=DEBUG'
    restart: always
    security_opt:
      - no-new-privileges:true
    depends_on:
      - socket-proxy
    ports:
      - "80:80"
      - "443:443"
    networks:
      - web
      - proxy
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./config/static.yml:/etc/traefik/traefik.yml
      - ./config/acme.json:/acme.json
      - ./config/dynamic.yml:/etc/traefik/dynamic.yml
    labels:
      traefik.enable: "true"

Static config:

serversTransport:
  insecureSkipVerify: true

certificatesResolvers:
  letsEncrypt:
    acme:
      email: "email@email.com"
      storage: "/acme.json"
      httpchallenge:
        entrypoint: http

entryPoints:
  http:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: "https"
          scheme: "https"
  https:
    address: ":443"

providers:
  docker:
    endpoint: "tcp://socket-proxy:2375"
    exposedByDefault: false
    network: "web"
  file:
    filename: "/etc/traefik/dynamic.yml"
    watch: true
  providersThrottleDuration: 10

Dynamic config:

http:
  routers:
    to-registry:
      rule: "Host(`registry.heliax.click`)"
      entryPoints:
        scheme: "https"
      service: "registry"
      tls:
        certResolver: "letsEncrypt"
        domains:
          - main: "registry.heliax.click"
            sans:
              - "www.registry.heliax.click"
    to-whoami:
      rule: "Host(`whoami.heliax.click`)"
      entryPoints: "https"
      service: "whoami"
      tls:
        certResolver: "letsEncrypt"
        domains:
          - main: "whoami.heliax.click"
            sans:
              - "www.whoami.heliax.click"

  services:
    registry:
      loadBalancer:
        servers:
          - url: "http://registry.heliax.internal"
    whoami:
      loadBalancer:
        servers:
          - url: "http://whoami.heliax.internal"

The second instance (listening on http://whoami.heliax.internal or http://registry.heliax.internal) doesn't receive any request. Below the only logs traefik is outputting:

{
    "Request": "{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\",\"RawFragment\":\"\"},\"Proto\":\"HTTP/2.0\",\"ProtoMajor\":2,\"ProtoMinor\":0,\"Header\":{\"Accept\":[\"*/*\"],\"User-Agent\":[\"curl/7.79.1\"],\"X-Forwarded-Host\":[\"whoami.heliax.click\"],\"X-Forwarded-Port\":[\"443\"],\"X-Forwarded-Proto\":[\"https\"],\"X-Forwarded-Server\":[\"64ebe5427112\"],\"X-Real-Ip\":[\"213.55.226.1\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"whoami.heliax.click\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"213.55.226.1:39602\",\"RequestURI\":\"/\",\"TLS\":null}",
    "level": "debug",
    "msg": "vulcand/oxy/roundrobin/rr: begin ServeHttp on request",
    "time": "2022-12-15T11:26:13Z"
}
{
    "ForwardURL": {
        "Scheme": "http",
        "Opaque": "",
        "User": null,
        "Host": "whoami.heliax.internal",
        "Path": "",
        "RawPath": "",
        "ForceQuery": false,
        "RawQuery": "",
        "Fragment": "",
        "RawFragment": ""
    },
    "Request": "{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\",\"RawFragment\":\"\"},\"Proto\":\"HTTP/2.0\",\"ProtoMajor\":2,\"ProtoMinor\":0,\"Header\":{\"Accept\":[\"*/*\"],\"User-Agent\":[\"curl/7.79.1\"],\"X-Forwarded-Host\":[\"whoami.heliax.click\"],\"X-Forwarded-Port\":[\"443\"],\"X-Forwarded-Proto\":[\"https\"],\"X-Forwarded-Server\":[\"64ebe5427112\"],\"X-Real-Ip\":[\"213.55.226.1\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"whoami.heliax.click\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"213.55.226.1:39602\",\"RequestURI\":\"/\",\"TLS\":null}",
    "level": "debug",
    "msg": "vulcand/oxy/roundrobin/rr: Forwarding this request to URL",
    "time": "2022-12-15T11:26:13Z"
}
{
    "Request": "{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\",\"RawFragment\":\"\"},\"Proto\":\"HTTP/2.0\",\"ProtoMajor\":2,\"ProtoMinor\":0,\"Header\":{\"Accept\":[\"*/*\"],\"User-Agent\":[\"curl/7.79.1\"],\"X-Forwarded-Host\":[\"whoami.heliax.click\"],\"X-Forwarded-Port\":[\"443\"],\"X-Forwarded-Proto\":[\"https\"],\"X-Forwarded-Server\":[\"64ebe5427112\"],\"X-Real-Ip\":[\"213.55.226.1\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"whoami.heliax.click\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"213.55.226.1:39602\",\"RequestURI\":\"/\",\"TLS\":null}",
    "level": "debug",
    "msg": "vulcand/oxy/roundrobin/rr: completed ServeHttp on request",
    "time": "2022-12-15T11:26:13Z"
}

curl whoami.heliax.click outputs: 404 page not found. Instead, the same command from inside the machine where traefik is outputs:

ubuntu: curl http://whoami.heliax.internal
Hostname: d0a0e6038bdb
IP: 127.0.0.1
IP: 10.0.10.39
IP: 172.18.0.3
RemoteAddr: 10.0.10.43:53414
GET / HTTP/1.1
Host: whoami.heliax.internal
User-Agent: curl/7.58.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.0.0.12
X-Forwarded-Host: whoami.heliax.internal
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 8fab7e3b23c1
X-Real-Ip: 10.0.0.12

Not sure whats going on, any help is appreciated!

You need dynamic config for the routing and services. I would use labels on the target containers (use ...rule=Host(example.com)||Host(www.example.com) instead of domains and sans) or use the dynamic file, but define services with the loadbalancer target.

What do u mean? As far as I understand, the sans/domain are just for the ssl certificate. Im already using in the dynamic config a loadbalancer. This is my dynamic config:

http:
  routers:
    to-registry:
      rule: "Host(`registry.heliax.click`)"
      entryPoints:
        scheme: "https"
      service: "registry"
      tls:
        certResolver: "letsEncrypt"
        domains:
          - main: "registry.heliax.click"
            sans:
              - "www.registry.heliax.click"
    to-whoami:
      rule: "Host(`whoami.heliax.click`)"
      entryPoints: "https"
      service: "whoami"
      tls:
        certResolver: "letsEncrypt"
        domains:
          - main: "whoami.heliax.click"
            sans:
              - "www.whoami.heliax.click"

  services:
    registry:
      loadBalancer:
        servers:
          - url: "http://registry.heliax.internal"
    whoami:
      loadBalancer:
        servers:
          - url: "http://whoami.heliax.internal"

You don't need the tls.domain part. Traefik LE will automatically create the certificates with the hostnames from rule. And it doesn't even help you to have a www. in the cert, if you don't have a matching rule for the domain.

Should be

rule: "Host( whoami.heliax.click ) || Host( www.whoami.heliax.click )"

Use backticks for the hostnames, they are not visible here.

How does Traefik know what the targets of the routers are? Do you want to use Docker Configuration Discovery, then you should place the hostnames on the service/container via labels. If you want to declare it manually, then you need to declare routers and service (with loadbalancer URLs).

Okay Ill remove the tsl.domain part. But everything else was already there, both routers and services:

http:
  routers:
    to-registry:
      rule: "Host(`registry.heliax.click`)"
      entryPoints:
        - "https"
      service: "registry"
    to-whoami:
      rule: "Host(`whoami.heliax.click`)"
      entryPoints:
        - "https"
      service: "whoami"

  services:
    registry:
      loadBalancer:
        servers:
          - url: "http://registry.heliax.internal"
    whoami:
      loadBalancer:
        servers:
          - url: "http://whoami.heliax.internal"

I can't use docker labels because I need to reverse proxy to a docker container in another machine (traefik and the target url, i.e http://whoami.heliax.internal are not on the same machine).
This still gives 404.

Sorry, didn't see your services, they were hidden below the fold.

Did you go into your Traefik container and try accessing your services directly?

docker exec -it <traefik-container> sh
wget http://whoami.heliax.internal/

PS: if you have multiple servers, you could just use Docker Swarm.

I solved it, it was due to the dns resolver. Thanks!

Then you can mark this as solved

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