Docker swarm working only with Docker provider and not dynamic file provider

When i use the labels directly on the service, it works as expected (Except I can't get another service on top of that) but not with an external dynamic configuration file provider.

My docker-compose.yml:
(using my actual e-mail and url)

version: "3.7"

services:
  proxy:
    image: traefik:v2.0.2
    volumes:
      # connect to docker socket for Traefik to listen to docker events
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/etc/traefik/traefik.toml:/etc/traefik/traefik.toml"
      - "/etc/traefik/dynamic/:/etc/traefik/dynamic/"
      # Store certificates in ./letsencrypt/acme.json
      - "./letsencrypt:/letsencrypt"
    networks:
      - proxy
    ports:
      - "443:443"
      - "80:80"
      - "3001:3001"
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager

  whoami:
    image: jwilder/whoami
    networks:
      - proxy

networks:
  proxy:
    driver: overlay

My Static config:

[log]
  level = "DEBUG"

[entryPoints]
  [entryPoints.web]
    address = ":80"
  [entryPoints.websecure]
    address = ":443"
  [entryPoints.app_staging]
    address = ":3001"

[providers]
  [providers.docker]
    endpoint = "unix:///var/run/docker.sock"
    network = "overlord_proxy"
    swarmMode = true
    watch = true
  # Enable the file provider to define routers / middlewares / services in a file
  [providers.file]
    debugLogGeneratedTemplate = true
    directory = "/etc/traefik/dynamic"
    watch = true

[certificatesResolvers]
  [certificatesResolvers.mytlschallenge]
    [certificatesResolvers.mytlschallenge.acme]
      email = "MYEMAIL"
      storage = "/letsencrypt/acme.json"
      tlschallenge = true

my dynamic config:

[http]
  [http.routers]
    [http.routers.whoami]
      entryPoints = ["web"]
      rule = "Host(`MYURL`)"
      service = "whoami"

    [http.routers.whoami-secure]
      entryPoints = ["websecure"]
      rule = "Host(`MYURL`)"
      service = "whoami"
      [http.routers.whoami.tls]
        certResolver = "mytlschallenge"

  [http.services]
    [http.services.whoami]
      enable = true
      [http.services.whoami.loadBalancer]
        [[http.services.whoami.loadBalancer.servers]]
          port = "8000"
          url = "http://whoami:8000"

  [http.middlewares]
    [http.middlewares.httpsredirect.redirectScheme]
      scheme = "https"

That doesn't work!! It only works when I place the flags directly onto the whoami service:

  whoami:
    image: jwilder/whoami
    networks:
      - proxy
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.whoami.rule=Host(`MYURL`)"
        - "traefik.http.routers.whoami.entrypoints=web"
        - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
        - "traefik.http.routers.whoami.middlewares=redirect-to-https"
        - "traefik.http.routers.whoami-secure.rule=Host(`MYURL`)"
        - "traefik.http.routers.whoami-secure.entrypoints=websecure"
        - "traefik.http.routers.whoami-secure.tls=true"
        - "traefik.http.routers.whoami-secure.tls.certresolver=mytlschallenge"
        - "traefik.http.services.whoami.loadbalancer.server.port=8000"

This is driving me crazy!

Hi.
I have the same issue with the labels using the 'file' provider and 'docker' provider together. In my stack I have even my own certificates for different FQDN's. The only solution that I found is:

  • static.yml file ==> log, entrypoint, providers (docker and file), api, metrics (using prometheus)
  • dynamic.yml file ==> TLS certificates block
  • Using flags directy onto each service

Buy the way, I am NOT using traefik + services without docker-compose stacks. Instead I am using terraform for deploying all services onto Docker Swarm API via TLS authentication.

1 Like

In your static config under [providers.docker] I see watch=true did you mean exposedByDefault=true ?

1 Like

My static file is like this:

# Static configuration:
# traefik_static.yml

# LOG --> Reading What's Happening
log:
  level: INFO
  format: common

# Accept HTTP and HTTPS
entryPoints:
  web:
    address: ':80'
  websecure:
    address: ':443'

# Providers ---> Docker, File
providers:
  docker:
    exposedByDefault: true
    swarmMode: true
    watch: true

  file:
    directory: /etc/traefik
    watch: true
  
# API --> Dashboard
api:
  insecure: true
  dashboard: true
  debug: true

# Enable Metrics with Prometheus
metrics:
  prometheus:
    entryPoint: traefik
    buckets:
      - 0.1
      - 0.3
      - 1.2
      - 5

I prefer yaml format :slight_smile:

1 Like

I like yaml better than toml, but I like lable and CLI config better than all of them. :slight_smile:

That said, I don't see your network: defined on the providers: section. Could that be it?

Hey! Thanks for your answers! I half got it working - one service works now on port 80 but my other service gets a '502 Bad Gateway' caused by: dial tcp 10.1.4.7:3000: connect: connection refused

This is the config:

traefik.toml

[log]
  level = "DEBUG"

[entryPoints]
  [entryPoints.web]
    address = ":80"
  [entryPoints.websecure]
    address = ":443"
  [entryPoints.staging]
    address = ":3000"

[providers]
  [providers.docker]
    endpoint = "unix:///var/run/docker.sock"
    network = "overlord_proxy"
    swarmMode = true
    watch = true
  # Enable the file provider to define routers / middlewares / services in a file
  [providers.file]
    debugLogGeneratedTemplate = true
    directory = "/etc/traefik/dynamic"
    watch = true

[certificatesResolvers]
  [certificatesResolvers.mytlschallenge]
    [certificatesResolvers.mytlschallenge.acme]
      email = "email"
      storage = "/letsencrypt/acme.json"
      tlschallenge = true

dyanmic config:

[http]
  [http.routers]
    [http.routers.whoami]
      entryPoints = ["web"]
      rule = "Host(`MYURL`)"
      service = "whoami"

    [http.routers.whoami-secure]
      entryPoints = ["websecure"]
      rule = "Host(`MYURL`)"
      service = "whoami"
      [http.routers.whoami.tls]
        certResolver = "mytlschallenge"

  [http.services]
    [http.services.whoami]
      enable = true
      [http.services.whoami.loadBalancer]
        [[http.services.whoami.loadBalancer.servers]]
          port = "8000"
          url = "http://whoami:8000"

  [http.middlewares]
    [http.middlewares.httpsredirect.redirectScheme]
      scheme = "https"

and the docker-compose.yml:

version: "3.7"

services:
  proxy:
    image: traefik:v2.0.2
    volumes:
      # connect to docker socket for Traefik to listen to docker events
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/etc/traefik/traefik.toml:/etc/traefik/traefik.toml"
      - "/etc/traefik/dynamic/:/etc/traefik/dynamic/"
      # Store certificates in ./letsencrypt/acme.json
      - "./letsencrypt:/letsencrypt"
    # command:
      #- "--providers.file=true"
      #- "--providers.file.filename=/traefik/traefik.toml"
    networks:
    - proxy
    ports:
      - "443:443"
      - "80:80"
      - "3000:3000"
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager

  whoami:
    image: jwilder/whoami
    networks:
    - proxy
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.whoami.rule=Host(`URL`)"
        - "traefik.http.routers.whoami.entrypoints=websecure"
        - "traefik.http.routers.whoami.service=whoami@file"

networks:
  proxy:
    driver: overlay

And that works! I have another docker-compose which runs another whoami service but I get a 502 bad gateway error (connection refused) when I navigate to MYURL:3000

version: "3.7"

services:
  staging:
    image: jwilder/whoami
    networks:
      - overlord_proxy
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.staging.rule=Host(`MYURL`)"
        - "traefik.http.routers.staging.entrypoints=staging"

        - "traefik.http.services.staging.loadbalancer.server.port=3000"
        - "traefik.http.routers.staging.service=staging@file"

networks:
  overlord_proxy:
    external: true

this is the dynamic config /etc/traefik/dynamic/staging.toml:

[http]
  [http.routers]
    [http.routers.staging]
      entryPoints = ["staging"]
      rule = "Host(`MYURL`)"
      service = "staging"

    [http.routers.staging-secure]
      entryPoints = ["staging"]
      rule = "Host(`MYURL`)"
      service = "staging"
      [http.routers.staging-secure.tls]
        certResolver = "mytlschallenge"

  [http.services]
    [http.services.staging]
      enable = true
      [http.services.staging.loadBalancer]
        [[http.services.staging.loadBalancer.servers]]
          port = "3000"
          url = "http://staging:3000"

  [http.middlewares]
    [http.middlewares.httpsredirect.redirectScheme]
      scheme = "https"

good catch! I changed that but still no luck! I think I'm close though :open_mouth:

does traefik have a check-config like nginx or apache? Seems like an easy one if you only wanted to catch required fields

I don't want to confuse this post too much :slight_smile:
Because I am deploying all docker-compose files with terraform !!! and the reason that you cannot see the network is because there is a terraform module for network, within traefik module itself !!

I have created another Post for this (it might be interested)

hhahah. ok, if feels like there are some layers that we should peel back.

I like automation but at this level it starts to feel like a black box. Can we post up the final generated configs that are actually deployed and run?

Hope this isn't spamming but I created a new topic as the problem changed from not being able to use dynamic config from getting a connection error

Maybe I should create a new tag :slight_smile:
Sorry I am new here...something like

Traefik v2 / Docker / Terraform

Best

Thanks for that !!

Good idea