Route to external docker app?

I'm wondering if its possible to route to an external docker app / public port.

I have a docker daemon (outside of my traefik docker-compose file) running a node app on my public ip @ port 3000. Is it possible to route traefik to the node app running in docker?

# this is the external docker daemon
# flood service
    flood:
        build: "flood"
        container_name: "flood"
        restart: "always"

        ports:
            - "3000:3000" # web UI port
# flood UI
labels:
            # enable this service
            - "traefik.enable=true"

            # redirect all HTTP requests to HTTPS
            - "traefik.http.routers.http-catchall.rule=hostregexp( `{host:.+}` )"
            - "traefik.http.routers.http-catchall.entrypoints=web"
            - "traefik.http.routers.http-catchall.middlewares=https-redirect@docker"

            # dashboard
            - "traefik.http.routers.api.rule=Host( `traefik.site.net` )"
            - "traefik.http.routers.api.entrypoints=web-secure"
            - "traefik.http.routers.api.tls.certresolver=ssl-resolver"
            - "traefik.http.routers.api.middlewares=auth"
            - "traefik.http.routers.api.service=api@internal"

            # flood UI
            - "traefik.http.routers.flood.rule=Host( `flood.site.net` )"
            - "traefik.http.routers.flood.entrypoints=web-secure"
            - "traefik.http.routers.flood.tls.certresolver=ssl-resolver"
            # - "traefik.http.services.flood.loadbalancer.server.url=http://0.0.0.0:3000"
            # - "traefik.http.services.flood.loadbalancer.server.port=3000"
            - "traefik.http.routers.flood.service=flood"

            # auth middleware
            - "traefik.http.middlewares.auth.basicauth.users=admin:pwhash"

            # HTTPS redirect middleware
            - "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"

SSL is a different story, I think i can do that at a later date by pointing certs in a seperate environment, im not too sure though... unless traefik can handle it for FloodUI too.

actually.. i figured out parts of this. first off, the other docker container needs

- "traefik.enable=true"

my other question is, how does traefik / docker name these services? is there a way to set this within docker-compose?

hello,

I recommend to set labels on each container:

version: "3.7"

services:
  traefik:
    image: traefik:v2.1.1
    command: >
      --log.level=INFO
      --api
      --providers.docker.exposedbydefault=false
      --entrypoints.web.address=:80
      --entrypoints.websecure.address=:443
      --certificatesresolvers.le.acme.email=your-email@your-domain.org
      --certificatesresolvers.le.acme.storage=acme.json
      --certificatesresolvers.le.acme.tlschallenge=true
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      # enable this service
      traefik.enable: true

      # redirect all HTTP requests to HTTPS
      traefik.http.routers.http-catchall.rule: hostregexp(`{host:.+}`)
      traefik.http.routers.http-catchall.entrypoints: web
      traefik.http.routers.http-catchall.middlewares: https-redirect@docker

      # dashboard
      traefik.http.routers.api.rule: Host(`traefik.site.net`)
      traefik.http.routers.api.entrypoints: websecure
      traefik.http.routers.api.tls.certresolver: le
      traefik.http.routers.api.middlewares: auth
      traefik.http.routers.api.service: api@internal

      # auth middleware
      traefik.http.middlewares.auth.basicauth.users: admin:pwhash

      # HTTPS redirect middleware
      traefik.http.middlewares.https-redirect.redirectscheme.scheme: https

  flood:
    build: "flood"
    container_name: "flood"
    restart: "always"
    labels:
      # enable this service
      traefik.enable: true

      # flood UI
      traefik.http.routers.flood.rule: Host(`flood.site.net`)
      traefik.http.routers.flood.entrypoints: websecure
      traefik.http.routers.flood.tls.certresolver: le
      traefik.http.services.flood.loadbalancer.server.port: 3000

also you don't need to expose the port of the flood application.


To create some routes to non-docker applications, you have to use the file provider.

this doesn't seem to work for me, no page response (gateway timeout). i mounted the docker 'sock' and tried load balancer, no luck.

this config, however.. works:

flood:
        build: "flood"
        container_name: "flood"
        restart: "always"

        depends_on:
            - "rtorrent"

        networks:
            - "internal"
            - "proxy"

        ports:
            - "3000:3000" # web UI port

        labels:
            # enable this service so traefik can see it
            - "traefik.enable=true"

            # route flood web UI
            - "traefik.http.routers.flood.rule=Host( `flood.site.net` )"
            - "traefik.http.routers.flood.entrypoints=web-secure"
            - "traefik.http.routers.flood.tls.certresolver=ssl-resolver"
            - "traefik.http.routers.flood.service=flood-rtorrent-flood-new"

but, why must i name the service in such a weird way? it's almost like it's reading my folder name rather than the name of the docker container name.

also, mind you, these are seperate containers (different compose files). any idea how i can fix this?

you don't need:

- "traefik.http.routers.flood.service=flood-rtorrent-flood-new"

You also don't need to expose port on flood container, you have to remove the following section:

ports:
  - "3000:3000"

As your are using several networks:

        networks:
            - "internal"
            - "proxy"

you have to specify the network to use:

Globally, with CLI flag (https://docs.traefik.io/v2.1/providers/docker/#network)

--providers.docker.network=proxy

or on container, with labels (https://docs.traefik.io/v2.1/routing/providers/docker/#traefikdockernetwork)

labels:
  traefik.docker.network: proxy

Take my file, it works.

version: "3.7"

services:
  traefik:
    image: traefik:v2.1.1
    command: >
      --log.level=INFO
      --api
      --providers.docker.exposedbydefault=false
      --entrypoints.web.address=:80
      --entrypoints.websecure.address=:443
      --certificatesresolvers.le.acme.email=your-email@your-domain.org
      --certificatesresolvers.le.acme.storage=acme.json
      --certificatesresolvers.le.acme.tlschallenge=true
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      # enable this service
      traefik.enable: true

      # redirect all HTTP requests to HTTPS
      traefik.http.routers.http-catchall.rule: hostregexp(`{host:.+}`)
      traefik.http.routers.http-catchall.entrypoints: web
      traefik.http.routers.http-catchall.middlewares: https-redirect@docker

      # dashboard
      traefik.http.routers.api.rule: Host(`traefik.site.net`)
      traefik.http.routers.api.entrypoints: websecure
      traefik.http.routers.api.tls.certresolver: le
      traefik.http.routers.api.middlewares: auth
      traefik.http.routers.api.service: api@internal

      # auth middleware
      traefik.http.middlewares.auth.basicauth.users: admin:pwhash

      # HTTPS redirect middleware
      traefik.http.middlewares.https-redirect.redirectscheme.scheme: https

  flood:
    image: containous/whoami
    container_name: "flood"
    labels:
      # enable this service
      traefik.enable: true

      # flood UI
      traefik.http.routers.flood.rule: Host(`flood.site.net`)
      traefik.http.routers.flood.entrypoints: websecure
      traefik.http.routers.flood.tls.certresolver: le
      traefik.http.services.flood.loadbalancer.server.port: 80

in this case, must i take out my networks? i said in my previous posts that this flood container runs as a node app on "localhost:3000". it exposes it to the public network interface. i just want to route traefik to :3000 so i can see the web ui, but, your code still gives me a gateway timeout. am i missing something? this is all very confusing

You are trying to do several things at the same time, so I recommend to progress step by step.

First step: no multiple network, no Let's Encrypt.

In my following example, I replaced your flood app by whoami, and I use localhost based domains:

version: "3.7"

services:
  traefik:
    image: traefik:v2.1.1
    command: >
      --log.level=INFO
      --api
      --providers.docker.exposedbydefault=false
      --entrypoints.web.address=:80
      --entrypoints.websecure.address=:443
      # --certificatesresolvers.le.acme.email=your-email@your-domain.org
      # --certificatesresolvers.le.acme.storage=acme.json
      # --certificatesresolvers.le.acme.tlschallenge=true
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      # enable this service
      traefik.enable: true

      # redirect all HTTP requests to HTTPS
      traefik.http.routers.http-catchall.rule: hostregexp(`{host:.+}`)
      traefik.http.routers.http-catchall.entrypoints: web
      traefik.http.routers.http-catchall.middlewares: https-redirect@docker

      # dashboard
      traefik.http.routers.api.rule: Host(`traefik.site.localhost`)
      traefik.http.routers.api.entrypoints: websecure
      # traefik.http.routers.api.tls.certresolver: le
      traefik.http.routers.api.tls: true
      traefik.http.routers.api.middlewares: auth
      traefik.http.routers.api.service: api@internal

      # auth middleware
      traefik.http.middlewares.auth.basicauth.users: admin:pwhash

      # HTTPS redirect middleware
      traefik.http.middlewares.https-redirect.redirectscheme.scheme: https

  flood:
    image: containous/whoami
    container_name: "flood"
    command: --port=3000
    labels:
      # enable this service
      traefik.enable: true
      
      # flood UI
      traefik.http.routers.flood.rule: Host(`flood.site.localhost`)
      traefik.http.routers.flood.entrypoints: websecure
      # traefik.http.routers.flood.tls.certresolver: le
      traefik.http.routers.flood.tls: true
      traefik.http.services.flood.loadbalancer.server.port: 3000
$ curl -k -L flood.site.localhost
Hostname: 3916e503a77c
IP: 127.0.0.1
IP: 172.20.0.3
RemoteAddr: 172.20.0.2:51780
GET / HTTP/1.1
Host: flood.site.localhost
User-Agent: curl/7.67.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.20.0.1
X-Forwarded-Host: flood.site.localhost
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: 0c2961ffb718
X-Real-Ip: 172.20.0.1
1 Like

thanks! i got it working, but in a slightly different way. i took your advice with the loadbalance and moved the docker container off public access. this works for me without issues:

version: "3.7"

services:
    traefik:
        image: "traefik:v2.1.1"
        container_name: "traefik"
        restart: "always"

        ports:
            - "80:80"
            - "443:443"
            - "8080:8080"
            - "8082:8082"

        networks:
            - "traefik-proxy"

        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock:ro" # listen for docker events (read only)
            - "./traefik/acme.json:/acme.json"               # save traefik SSL cert data here
            - "./traefik/logs:/logs"                         # save log files here

        environment:
            # cloudflare account info
            CF_API_EMAIL: "foo"
            CF_API_KEY: "bar"

        command:
            # traefik options
            - "--log.level=ERROR"
            - "--log.format=json"
            - "--log.filePath=logs/traefik.log"
            - "--api=true"
            - "--api.dashboard=true"
            - "--api.debug=false"
            - "--ping=true"
            - "--ping.entryPoint=ping"

            # docker provider
            - "--providers.docker=true"
            - "--providers.docker.exposedbydefault=false"
            - "--providers.docker.watch=true"
            - "--providers.docker.network=traefik-proxy"

            # entry points
            - "--entrypoints.web.address=:80"
            - "--entrypoints.web-secure.address=:443"
            - "--entryPoints.ping.address=:8082"

            # ssl options
            - "--certificatesresolvers.ssl-resolver.acme.email=admin@site.net"
            - "--certificatesresolvers.ssl-resolver.acme.storage=acme.json"
            - "--certificatesResolvers.ssl-resolver.acme.tlsChallenge=true"
            - "--certificatesResolvers.ssl-resolver.acme.dnsChallenge=true"
            - "--certificatesResolvers.ssl-resolver.acme.dnsChallenge.provider=cloudflare"

        labels:
            # enable this service
            - "traefik.enable=true"

            # redirect all HTTP requests to HTTPS
            - "traefik.http.routers.http-catchall.rule=hostregexp( `{host:.+}` )"
            - "traefik.http.routers.http-catchall.entrypoints=web"
            - "traefik.http.routers.http-catchall.middlewares=https-redirect"

            # set up primary domain & HTTPS
            - "traefik.http.routers.main.rule=Host( `site.net` )"
            - "traefik.http.routers.main.tls=true"
            - "traefik.http.routers.main.tls.certresolver=ssl-resolver"
            - "traefik.http.routers.main.tls.domains[0].main=site.net"
            - "traefik.http.routers.main.tls.domains[0].sans=*.site.net"

            # dashboard
            - "traefik.http.routers.traefik.rule=Host( `traefik.site.net` )"
            - "traefik.http.routers.traefik.tls=true"
            - "traefik.http.routers.traefik.entrypoints=web-secure"
            - "traefik.http.routers.traefik.middlewares=auth"
            - "traefik.http.routers.traefik.service=api@internal"

            # auth middleware
            - "traefik.http.middlewares.auth.basicauth.users=admin:pw_hash"

            # HTTPS redirect middleware
            - "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"

networks:
    internal:
        external: false

    traefik-proxy:
        name: "traefik-proxy"
# flood service (a web UI for rTorrent)
flood:
    build: "flood"
    container_name: "flood"
    restart: "always"

    networks:
        - "internal"
        - "traefik-proxy"

    labels:
        # enable this service so traefik can see it
        - "traefik.enable=true"

        # route flood web UI
        - "traefik.http.routers.flood.rule=Host( `flood.site.net` )"
        - "traefik.http.routers.flood.tls=true"
        - "traefik.http.routers.flood.entrypoints=web-secure"
        - "traefik.http.services.flood.loadbalancer.server.port=3000"
            
networks:
    internal:
        external: false

    traefik-proxy:
        external:
            name: "traefik-proxy"

am i missing anything or doing anything silly here? it works very well, and i have SSL wildcard it seems (instead of exposing all my subdomains).