Defining non docker services with labels

I have all of my docker based services successfully running traefik v2.0.1. I however also want to setup the same for my external services such as my pihole's running on rPi3's. As I understand it I can do it via file provider like:

http:
  routers:
    pihole-1:
      entryPoints:
        - web
      rule: "Host(`pihole-1.homenet.mydomain.com`)"
      service: pihole-1
      tls:
        certResolver: "mydnschallenge"
        domains:
          - main: "mydomain.com"
          - sans: "*.mydomain.com"
  services:
    pihole-1:
      loadBalancer:
        servers:
          - url: "http://192.168.1.2:80"
        passHostHeader: true

But is there a way to do it via labels? I cannot see a way to define the URL IP to the specific service. Does this mean I need to convert all of my docker labels for all of my containers into a file such as rules.yml and use that method instead?

Hello,

I'm not sure to understand your goal.

You can use multiple providers a the same time: docker, file, ...

That I didn't realize. I assumed it was only possible to use one at a time..

I added:

      - "--providers.file.filename=rules.yml"
      - "--providers.file.directory=/opt/docker/traefik"
      - "--providers.file.watch=true"

To the docker-compose commands, I can see that file is listed under traefik dashboard providers now but it does not appear to see/read the rules.yml file as the services are not being created that are defined within.

--providers.file.filename and --providers.file.directory are mutually exclusive, so you have to use only one, I recommend --providers.file.directory

I've been struggling to get traefik to read the rules.yml still. No router or services that are defined within the rules.yml are being created, am I just mounting it to the wrong directory?

Related file provider configs in my docker-compose.yml:

command:
 "--providers.file.directory=/etc/traefik"
 "--providers.file.watch=true"
 "--providers.docker=true"
 "--providers.docker.exposedbydefault=false"
volumes:
- /opt/docker/traefik/rules.yml:/etc/traefik/rules.yml

And here is my rules.yml:

http:
  routers:
    pihole-1:
      entryPoints:
        - websecure
      rule: "Host(`pihole-1.mydomain.com`)"
      tls:
        certResolver: "mydnschallenge"
        domains:
          - main: "mydomain.com"
          - sans: "*.mydomain.com"
          service: pihole-1
  services:
    pihole-1:
      loadBalancer:
        servers:
          - url: "http://192.168.1.2:80"
        passHostHeader: true

Thank you for the help Idez, I am so close to getting all my services covered, I've spent the past 2 hours trying to debug.

Try this version (same content but different syntax):

http:
  routers:
    pihole-1:
      entryPoints:
        - websecure
      rule: "Host(`pihole-1.mydomain.com`)"
	  service: pihole-1
      tls:
        certResolver: "mydnschallenge"
        domains:
          - main: "mydomain.com"
            sans:
              - "*.mydomain.com"
  services:
    pihole-1:
      loadBalancer:
        servers:
          - url: "http://192.168.1.2:80"
        passHostHeader: true

Thanks for taking a look over my syntax I gave it a shot but traefik still isn't creating the router or service, I'm thinking that perhaps I am not mounting the rules.yml into the right directory for traefik to find since there is nothing inside of /etc/traefik before I mount the rules there.

Here's my piece

    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock'
      - '.\traefik_2.0.1\rules.yml:/rules.yml'
    env_file:
      - .env
    restart: unless-stopped
    domainname: '${ZONE}'
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=web"
      - "traefik.http.routers.traefik.rule=Host(`traefik.localhost`)"
      - "traefik.http.routers.traefik_https.entrypoints=web-secure"
      - "traefik.http.routers.traefik_https.rule=Host(`traefik.localhost`)"      
      - "traefik.http.routers.traefik_https.tls=true"
      - "traefik.http.routers.traefik_https.tls.certresolver=basic"
#      - "traefik.http.routers.traefik_https.service=api@internal"
      - "traefik.http.routers.traefik_https.tls.domains[0].main=*.${ZONE}"
      - "traefik.http.routers.traefik_https.tls.domains[0].sans=${ZONE}"         
      - "traefik.http.services.traefik.loadbalancer.server.port=8080"     
      - "traefik.http.middlewares.testHeader.headers.framedeny=true"
      - "traefik.http.middlewares.testHeader.headers.sslredirect=true"      
      # middleware redirect
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      # global redirect to https
      - "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.redirs.entrypoints=web"
      - "traefik.http.routers.redirs.middlewares=redirect-to-https"   
    environment:
      - CF_API_EMAIL=${EMAIL}
      - CF_API_KEY=${API_KEY}
      - com.ouroboros.enable=true
      - TZ=Europe/Bucharest
    command:
      - '--log.level=DEBUG'
      - '--log.format=json'
      - '--global.checkNewVersion=true'
      - '--global.sendAnonymousUsage=false'
      - '--entryPoints.web.address=:80'
      - '--entryPoints.web-secure.address=:443'
      - '--api'
      - '--api.debug'
      - '--api.insecure'
      - '--api.dashboard'
      - '--ping'
      - '--providers.docker.exposedByDefault=false'
      - '--providers.docker.watch=true'
      - '--providers.docker.swarmMode=false'
      - '--providers.file.filename=/rules.yml'
      - '--providers.file.watch=true'

Thanks for sharing, its already pretty similar to mine I did turn on debug though and went through the logs, here is what I am getting:

time="2019-10-15T14:26:40-04:00" level=info msg="Starting provider *file.Provider {\"watch\":true,\"filename\":\"rules.yml\"}"
time="2019-10-15T14:26:40-04:00" level=error msg="Cannot start the provider *file.Provider: yaml: line 6: did not find expected key"

There's a problem with your yaml file on line 6. Can you please post it?

It is the same rules.yml as what you posted above with the altered syntax.

http:
  routers:
    pihole-1:
      entryPoints:
        - websecure
      rule: "Host(`pihole-1.mydomainname.com`)"
          service: pihole-1
      tls:
        certResolver: "mydnschallenge"
        domains:
          - main: "mydomainname.com"
            sans:
              - "*.mydomainname.com"
  services:
    pihole-1:
      loadBalancer:
        servers:
          - url: "http://192.168.1.2:80"
        passHostHeader: true

Line 6 would be the router rule. (sanitized)

Here is my docker-compose:

services:
  traefik:
    container_name: "traefik"
    image: traefik:v2.0.2
    hostname: "traefik"
    command:
      - "--log.level=DEBUG"
      - "--accesslog=true"
      - "--api.insecure=true"
      - "--providers.file.filename=rules.yml"
#      - "--providers.file.directory=/"
      - "--providers.file.watch=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mydnschallenge.acme.dnschallenge=true"
      - "--certificatesresolvers.mydnschallenge.acme.dnschallenge.provider=cloudflare"
      - "--certificatesresolvers.mydnschallenge.acme.email=[REMOVED]"
      - "--certificatesresolvers.mydnschallenge.acme.storage=/letsencrypt/acme.json"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.homenet.mydomainname.com`)"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.tls.certresolver=mydnschallenge"
      - "traefik.http.services.traefik.loadbalancer.server.port=8080"
      - "traefik.http.middlewares.traefik_redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.traefik_insecure.rule=Host(`traefik.homenet.mydomainname.com`)"
      - "traefik.http.routers.traefik_insecure.entrypoints=web"
      - "traefik.http.routers.traefik_insecure.middlewares=traefik_redirect@docker"
    volumes:
      - /opt/docker/traefik:/letsencrypt
      - /opt/docker/traefik/rules.yml:/rules.yml
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    environment:
      - CLOUDFLARE_EMAIL=[REMOVED]
      - CLOUDFLARE_API_KEY=[REMOVED]
      - TZ=America/New_York
    networks:
      - default
    restart: unless-stopped

You had 3 spaces instead of 2 on line 7:
Try this:

http:
  routers:
    pihole-1:
      entryPoints:
        - websecure
      rule: "Host(`pihole-1.mydomainname.com`)"
      service: pihole-1
      tls:
        certResolver: "mydnschallenge"
        domains:
          - main: "mydomainname.com"
            sans:
              - "*.mydomainname.com"
  services:
    pihole-1:
      loadBalancer:
        servers:
          - url: "http://192.168.1.2:80"
        passHostHeader: true
1 Like

Whoops, well that worked! Thank you.

My pleasure, everything ok now ?

I'm sure its just some small config changes to the file to make it work now as I am getting an unable to connect error to https://pihole-1.homenet.mydomain.com.

I do see the router and service from the file in the dashboard now though.

time="2019-10-16T10:09:59-04:00" level=debug msg="Try to challenge certificate for domain [pihole-1.homenet.mydomain.com] founded in HostSNI rule" routerName=pihole-1 rule="Host(`pihole-1.homenet.mydomain.com`)" providerName=mydnschallenge.acme
time="2019-10-16T10:09:59-04:00" level=debug msg="Looking for provided certificate(s) to validate [\"pihole-1.homenet.mydomain.com\"]..." providerName=mydnschallenge.acme routerName=pihole-1 rule="Host(`pihole-1.homenet.mydomain.com`)"
time="2019-10-16T10:09:59-04:00" level=debug msg="No ACME certificate generation required for domains [\"pihole-1.homenet.mydomain.com\"]." providerName=mydnschallenge.acme routerName=pihole-1 rule="Host(`pihole-1.homenet.mydomain.com`)"

Also making changes to the rules.yml seems to require a restart of traefik for the configs to take, I thought traefik would watch for changes automatically without a restart required.

The fact that the log mentions HostSNI is weird as in the last config that you shared you didn't had anything related to HostSNI. As per documentation HostSNI is related to the TCP routers and Host is related to the HTTP routers.

Host
HostSNI

I would recommend a double check of the latest version of your files (yml and compose) and then posting them again here if you didn't find anything out of the ordinary.

I am seeing that in my logs but yeah I'm not certain as my files don't contain anything relevant to tcp I think, none of my other containers are using it. I did make some changes to my files which are below, namely I took your approach to redirecting http to https as it was more elegant then my own.

services:
  traefik:
    container_name: "traefik"
    image: traefik:v2.0.2
    hostname: "traefik"
    command:
      - "--log.level=DEBUG"
      - "--accesslog=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.file.filename=rules.yml"
      - "--providers.file.watch=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mydnschallenge.acme.dnschallenge=true"
      - "--certificatesresolvers.mydnschallenge.acme.dnschallenge.provider=cloudflare"
      - "--certificatesresolvers.mydnschallenge.acme.email=[REMOVED]"
      - "--certificatesresolvers.mydnschallenge.acme.storage=/letsencrypt/acme.json"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.homenet.mydomain.com`)"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.tls.certresolver=mydnschallenge"
      - "traefik.http.routers.traefik.tls.domains[0].main=*.homenet.mydomain.com"
      - "traefik.http.routers.traefik.tls.domains[0].sans=homenet.mydomain.com,mydomain.com"
      - "traefik.http.services.traefik.loadbalancer.server.port=8080"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.redirs.entrypoints=web"
      - "traefik.http.routers.redirs.middlewares=redirect-to-https"
    volumes:
      - /opt/docker/traefik:/letsencrypt
      - /opt/docker/traefik/rules.yml:/rules.yml
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    environment:
      - CLOUDFLARE_EMAIL=[REMOVED]
      - CLOUDFLARE_API_KEY=[REMOVED]
      - TZ=America/New_York
    networks:
      - default
    restart: unless-stopped

I added a few more services and routers to the rules.yml to see if any of them will load, they are showing inside of traefik dashboard but again the pages will not load at all, internal docker containers work correctly its just these external services that aren't functioning. I have them added the same way inside of my piholes DNS (lan.list) so they should be routing within my network.

http:
  routers:
    pihole-1:
      entryPoints:
        - websecure
      rule: "Host(`pihole-1.homenet.mydomain.com`)"
      middlewares:
        - redirect-to-https@docker
      service: pihole-1
      tls:
        certResolver: "mydnschallenge"
  services:
    pihole-1:
      loadBalancer:
        servers:
          - url: "http://192.168.1.2/admin"
        passHostHeader: true

http:
  routers:
    pihole-2:
      entryPoints:
        - websecure
      rule: "Host(`pihole-2.homenet.mydomain.com`)"
      middlewares:
        - redirect-to-https@docker
      service: pihole-2
      tls:
        certResolver: "mydnschallenge"
  services:
    pihole-2:
      loadBalancer:
        servers:
          - url: "http://192.168.1.3/admin"
        passHostHeader: true

http:
  routers:
    unifi:
      entryPoints:
        - websecure
      rule: "Host(`unifi.homenet.mydomain.com`)"
      middlewares:
        - redirect-to-https@docker
      service: unifi
      tls:
        certResolver: "mydnschallenge"
  services:
    unifi:
      loadBalancer:
        servers:
          - url: "https://192.168.1.2:8443"
        passHostHeader: true

http:
  routers:
    esxi:
      entryPoints:
        - websecure
      rule: "Host(`esxi.homenet.mydomain.com`)"
      middlewares:
        - redirect-to-https@docker
      service: esxi
      tls:
        certResolver: "mydnschallenge"
  services:
    esxi:
      loadBalancer:
        servers:
          - url: "https://192.168.1.4/ui/"
        passHostHeader: true

Here are some relevant logs:

time="2019-10-17T08:57:43-04:00" level=debug msg="Start TCP Server" entryPointName=traefik
time="2019-10-17T08:57:43-04:00" level=info msg="Starting provider aggregator.ProviderAggregator {}"
time="2019-10-17T08:57:43-04:00" level=debug msg="Start TCP Server" entryPointName=websecure
time="2019-10-17T08:57:43-04:00" level=debug msg="Start TCP Server" entryPointName=web
time="2019-10-17T08:57:44-04:00" level=debug msg="Looking for provided certificate(s) to validate [\"esxi.homenet.mydomain.com\"]..." providerName=mydnschallenge.acme routerName=esxi rule="Host(`esxi.homenet.mydomain.com`)"
time="2019-10-17T08:57:44-04:00" level=debug msg="Looking for provided certificate(s) to validate [\"pihole-2.homenet.mydomain.com\"]..." routerName=pihole-2 rule="Host(`pihole-2.homenet.mydomain.com`)" providerName=mydnschallenge.acme
time="2019-10-17T08:57:44-04:00" level=debug msg="Looking for provided certificate(s) to validate [\"pihole-1.homenet.mydomain.com\"]..." rule="Host(`pihole-1.homenet.mydomain.com`)" providerName=mydnschallenge.acme routerName=pihole-1
time="2019-10-17T08:57:44-04:00" level=debug msg="Looking for provided certificate(s) to validate [\"unifi.homenet.mydomain.com\"]..." routerName=unifi rule="Host(`unifi.homenet.mydomain.com`)" providerName=mydnschallenge.acme
time="2019-10-17T08:57:44-04:00" level=debug msg="Adding certificate for domain(s) pihole-2.homenet.mydomain.com"
time="2019-10-17T08:57:44-04:00" level=debug msg="Adding certificate for domain(s) cloud.mydomain.com"
time="2019-10-17T08:57:44-04:00" level=debug msg="Adding certificate for domain(s) pihole-1.homenet.mydomain.com"
time="2019-10-17T08:57:44-04:00" level=debug msg="Adding certificate for domain(s) *.homenet.mydomain.com,mydomain.com,homenet.mydomain.com"
time="2019-10-17T08:57:44-04:00" level=debug msg="No ACME certificate generation required for domains [\"pihole-2.homenet.mydomain.com\"]." routerName=pihole-2 rule="Host(`pihole-2.homenet.mydomain.com`)" providerName=mydnschallenge.acme
time="2019-10-17T08:57:44-04:00" level=debug msg="No ACME certificate generation required for domains [\"pihole-1.homenet.mydomain.com\"]." providerName=mydnschallenge.acme routerName=pihole-1 rule="Host(`pihole-1.homenet.mydomain.com`)"
time="2019-10-17T08:57:44-04:00" level=debug msg="No ACME certificate generation required for domains [\"esxi.homenet.mydomain.com\"]." providerName=mydnschallenge.acme routerName=esxi rule="Host(`esxi.homenet.mydomain.com`)"
time="2019-10-17T08:57:44-04:00" level=debug msg="No ACME certificate generation required for domains [\"unifi.homenet.mydomain.com\"]." routerName=unifi rule="Host(`unifi.homenet.mydomain.com`)" providerName=mydnschallenge.acme
time="2019-10-17T08:57:44-04:00" level=debug msg="Try to challenge certificate for domain [cloud.mydomain.com] founded in HostSNI rule" providerName=mydnschallenge.acme routerName=nextcloud rule="Host(`cloud.mydomain.com`)"
time="2019-10-17T08:57:44-04:00" level=debug msg="Looking for provided certificate(s) to validate [\"cloud.mydomain.com\"]..." providerName=mydnschallenge.acme routerName=nextcloud rule="Host(`cloud.mydomain.com`)"
time="2019-10-17T08:57:44-04:00" level=debug msg="Creating middleware" middlewareType=Pipelining entryPointName=websecure routerName=pihole-1@file serviceName=pihole-1 middlewareName=pipelining
time="2019-10-17T08:57:44-04:00" level=debug msg="Creating load-balancer" serviceName=pihole-1 entryPointName=websecure routerName=pihole-1@file
time="2019-10-17T08:57:44-04:00" level=debug msg="Creating server 0 http://192.168.1.2/admin" serverName=0 entryPointName=websecure routerName=pihole-1@file serviceName=pihole-1
time="2019-10-17T08:57:44-04:00" level=debug msg="Added outgoing tracing middleware pihole-1" entryPointName=websecure routerName=pihole-1@file middlewareName=tracing middlewareType=TracingForwarder
time="2019-10-17T08:57:44-04:00" level=debug msg="Creating middleware" entryPointName=websecure routerName=pihole-1@file middlewareType=RedirectScheme middlewareName=redirect-to-https@docker
time="2019-10-17T08:57:44-04:00" level=debug msg="Setting up redirection to https " middlewareType=RedirectScheme middlewareName=redirect-to-https@docker entryPointName=websecure routerName=pihole-1@file
time="2019-10-17T08:57:44-04:00" level=debug msg="Adding tracing to middleware" middlewareName=redirect-to-https@docker entryPointName=websecure routerName=pihole-1@file