# Docker dynamic labels when not using swarm

**URL:** <https://community.traefik.io/t/docker-dynamic-labels-when-not-using-swarm/4480>\
**Category:** Traefik v2\
**Tags:** docker\
**Created:** [February 18, 2020, 12:29pm UTC](https://community.traefik.io/t/docker-dynamic-labels-when-not-using-swarm/4480 "2020-02-18T12:29:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![stevegroom](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/stevegroom/32/1696_2.png) [@stevegroom](https://community.traefik.io/u/stevegroom)\
**Post date:** [February 18, 2020, 12:29pm UTC](https://community.traefik.io/t/docker-dynamic-labels-when-not-using-swarm/4480/1 "2020-02-18T12:29:26Z")

</div>

I am trying to move a Traefik web service config from a yml file to embedding the config as labels in the docker-compose file. I have tried several times and not seen any evidence that the labels are being read.

The docs [https://docs.traefik.io/providers/docker/#docker-swarm-mode](https://docs.traefik.io/providers/docker/#docker-swarm-mode) _seem_ to state that config can be read from the docker-compose file. And several searches show people have to move the labels to the deploy section of the docker-compose file. As I understand it that is only when running a docker swarm.

- I am not running a swarm
- I have multiple docker-compose files on the same server. Only the labels in the Traefik docker-compose file (traefik and whoami services) seem to work.

Do I have to move over to a swarm to be able to take advantage of the labels?

```auto
version: '3'
services:
  web:
    build: nginx

# networks:
# - outside
# - default

    #ports:
      # Port should be set in docker-compose.override.yml
      # - "9999:80"

    volumes:
      - ./src/public:/usr/share/nginx/html:ro

      - ./nginx/sites-enabled:/etc/nginx/sites-enabled
      - ./nginx/snippets:/etc/nginx/snippets
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./files:/files
      - /var/run/docker.sock:/var/run/docker.sock:ro

    labels:
      - "traefik.enable=true"

      - "traefik.http.routers.web.entrypoints=websecure"
      - "traefik.http.routers.web.rule=Host(`fiagt.gxxxs.page`)"
      - "traefik.http.routers.web.service=fiagt"

      # Authentication
      - "traefik.http.routers.web.middlewares=usersfile@file"

      # Certificate name and san
      - "traefik.http.routers.web.tls.certresolver=basic"
      - "traefik.http.routers.web.tls.domains[0].main=gxxxs.page"
      - "traefik.http.routers.web.tls.domains[0].sans=*.gxxxs.page"

      # Services
      - "traefik.http.services.web.servers.url=http://192.168.1.130:8007/index.php"
      - "traefik.http.services.web.loadbalancer.server.port=80"
      - "traefik.http.services.web.passhostheader=false"
      - "traefik.http.services.web.hostname=fiagt.docker.dev.gxxxs.page"

    links:
      - php

  php:
    build: php

# networks:
# - default

    ulimits:
      nproc: 65535
      nofile:
        soft: 20000
        hard: 40000

    #mem_limit: 4000000000
    #memswap_limit: 8000000000
    privileged: true

    volumes:
      - ./src/public:/usr/share/nginx/html
      # On the php service run ps aux | grep php-fpm to see where the php-fpm.conf is found
      #decided to stop sharing these files and use the Dockerfile to create the required entries
      #- ./php/conf:/usr/local/etc
      - ./files:/files
    links:
      - db

  # The Database
  db:
    image: mysql:5.7
    volumes:
      - ./mysql/db:/var/lib/mysql
      - ./mysql/source:/docker-entrypoint-initdb.d
    #restart: always
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "no"
      MYSQL_ROOT_PASSWORD: 
      MYSQL_DATABASE: fiagt
      MYSQL_USER: root
      MYSQL_PASSWORD: 
    ports:
      - "33061:3306"

# Add a phpmyadmin container when needed.
# http://docker.dev:8000 to launch
# credentials:
  phpmyadmin:
    image: nazarpc/phpmyadmin

    #ports:
    #- "9998:80"

    links:
      - db:mysql

    labels:
      - "traefik.enable=true"

      - "traefik.http.routers.phpmyadmin.entrypoints=websecure"
      - "traefik.http.routers.phpmyadmin.rule=Host(`fiagtadm.gxxxs.page`)"
      - "traefik.http.routers.phpmyadmin.service=fiagtadm"

      # Authentication
      - "traefik.http.routers.phpmyadmin.middlewares=usersfile@file"

      # Certificate name and san
      - "traefik.http.routers.phpmyadmin.tls.certresolver=basic"
      - "traefik.http.routers.phpmyadmin.tls.domains[0].main=gxxxs.page"
      - "traefik.http.routers.phpmyadmin.tls.domains[0].sans=*.gxxxs.page"

      # Services
      - "traefik.http.services.phpmyadmin.servers.url=http://192.168.1.130:9007/index.php"
      - "traefik.http.services.phpmyadmin.passhostheader=false"

#networks:
# outside:
# external:
# name: adbname

```

---

<div class="post-metadata">

**Author:** ![ldez](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/ldez/32/5_2.png) [@ldez](https://community.traefik.io/u/ldez)\
**Post date:** [February 18, 2020, 1:28pm UTC](https://community.traefik.io/t/docker-dynamic-labels-when-not-using-swarm/4480/2 "2020-02-18T13:28:20Z")

</div>

Hello,

You don't have to move to swarm.

You need to manage the different networks related to your docker-compose files.

* * *

> [@stevegroom](#):
>
> ```auto
> # Services
> - "traefik.http.services.web.servers.url=http://192.168.1.130:8007/index.php"
> - "traefik.http.services.web.loadbalancer.server.port=80"
> - "traefik.http.services.web.passhostheader=false"
> - "traefik.http.services.web.hostname=fiagt.docker.dev.gxxxs.page"
> 
> ```

> [@stevegroom](#):
>
> ```auto
> # Services
> - "traefik.http.services.phpmyadmin.servers.url=http://192.168.1.130:9007/index.php"
> - "traefik.http.services.phpmyadmin.passhostheader=false"
> 
> ```

The exhaustive list of labels that you can use for services: [Docker | Traefik | v2.1](https://docs.traefik.io/v2.1/routing/providers/docker/#services)

As the IP are dynamic (related to Docker) and detected automatically by Traefik, you just have to define (if needed) the port by using `traefik.http.services.<random_name>.loadbalancer.server.port`

---

<div class="post-metadata">

**Author:** ![stevegroom](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/stevegroom/32/1696_2.png) [@stevegroom](https://community.traefik.io/u/stevegroom)\
**Post date:** [February 18, 2020, 4:10pm UTC](https://community.traefik.io/t/docker-dynamic-labels-when-not-using-swarm/4480/3 "2020-02-18T16:10:26Z")

</div>

Thank you Idez,  
the docs are helpful, but I did not succeed yet.

First a historic statement - I learnt to use docker on an old Mac with VirtualBox and networking was a nightmare to get working. I recently moved my docker env to Ubuntu and did not think to review the network settings - I'd be happy if I can remove all the network references - I tried - but so far I kept getting problems.

Back to the settings - I removed the unsupported parameters and tried again. Still no luck ( I assume a docker-compose down / docker-compose up for my app will trigger Traefik to refresh the list of routers).

For simplicity, I'll omit the 2nd service.

```auto
version: '3'

networks:
  default:
    external:
      name: nucnuc

services:
  web:
    build: nginx

    # networks:
    # - nucnuc
    # - default

    ports:
      # Set the required port number here and update launcher :: siteCatalog.yml
      - "8007:80"
    #ports:
      # Port should be set in docker-compose.override.yml
      # - "9999:80"

    volumes:
      - ./src/public:/usr/share/nginx/html:ro

      - ./nginx/sites-enabled:/etc/nginx/sites-enabled
      - ./nginx/snippets:/etc/nginx/snippets
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./files:/files
      - /var/run/docker.sock:/var/run/docker.sock:ro

    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=nucnuc"

      - "traefik.http.routers.web.rule=Host(`fiagt.gxxxs.page`)"
      - "traefik.http.routers.web.entrypoints=websecure"

      - "traefik.http.routers.web.service=fiagt"

      # Authentication
      - "traefik.http.routers.web.middlewares=usersfile@file"

      # Certificate name and san
      - "traefik.http.routers.web.tls.certresolver=basic"
      - "traefik.http.routers.web.tls.domains[0].main=gxxxs.page"
      - "traefik.http.routers.web.tls.domains[0].sans=*.gxxxs.page"

      # Services
      - "traefik.http.services.fiagt.loadbalancer.server.port=8007"
      - "traefik.http.services.fiagt.loadbalancer.server.scheme=http"
      - "traefik.http.services.fiagt.passhostheader=false"

    links:
      - php
...omitted

```

Should the port be the internal port or the published port ?

traefix services has  
`- --providers.docker.exposedbydefault=false`

which results in:

```auto
traefik_1 | time="2020-02-18T16:00:19Z" level=debug msg="Filtering disabled container" providerName=docker container=web-fiagt-f8e56f8ab78916eddc35f99a819e28eb245a158b86058afa0469118838d7a644
traefik_1 | time="2020-02-18T16:00:19Z" level=debug msg="Filtering disabled container" container=php-fiagt-263b9a6865705787fa78cdf960f4bfd2ce09cee397a81885377f001fd26d23af providerName=docker
traefik_1 | time="2020-02-18T16:00:19Z" level=debug msg="Filtering disabled container" providerName=docker container=phpmyadmin-fiagt-8c0cedbb6c07ec241d2bec97bbde3386f17a55e88dbe6603c0859a389c5789c1
traefik_1 | time="2020-02-18T16:00:19Z" level=debug msg="Filtering disabled container" providerName=docker container=db-fiagt-6f3d844d133568f3b94e144748eb0ecaf0e9909f14ff4016c47ed2e0d96013ff
traefik_1 | time="2020-02-18T16:00:19Z" level=debug msg="Filtering disabled container" providerName=docker container=jaeger-agent-jaeger-1fa2fd0ca2fd0870b2f09bac1d21201b8437455cc92fdd1c03db29b35486bd2a
traefik_1 | time="2020-02-18T16:00:19Z" level=debug msg="Filtering disabled container" providerName=docker container=jaeger-collector-jaeger-826afb0c5c9272e6bdaf976dbb7e22712bc2895d6b2370c52e09e70d04f83dde
traefik_1 | time="2020-02-18T16:00:19Z" level=debug msg="Filtering disabled container" providerName=docker container=cassandra-jaeger-73e7b1bbf82c84731c09b7a35ebfe4c5064641c3fe56e0f6f736742b214d480d

```

But I think that is expected.

For completeness here is the traefik docker-compose file.

```auto
version: '3'

networks:
  default:
    external:
      name: nucnuc

services:
  traefik:
    # The official v2.1 Traefik docker image
    image: traefik:v2.1.4
# networks:
# - nucnuc
    command: 
      # - --accesslog=true
      - --api
      - --api.insecure=false # Enables the web UI
      - --entrypoints.web.address=:80 #Declares the web entrypoint in Traefik
      - --entrypoints.websecure.address=:443 #Declares the websecure entrypoint in Traefik
      - --global.sendAnonymousUsage=true
      - --log.level=DEBUG
      - --providers.docker=true #and tells Traefik to listen to docker
      # Enable a tls challenge named "basic"
      - "--certificatesresolvers.basic.acme.email=steve@groom.ch"
      - "--certificatesresolvers.basic.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.basic.acme.dnschallenge.provider=cloudflare"
      # - "--certificatesresolvers.basic.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      # Providers
      - --providers.file.directory=/conf
      - --providers.file.watch=true
      - --providers.docker.exposedbydefault=false
      - --tracing=true
      - --tracing.serviceName=traefik
      - --tracing.jaeger=true
      - --tracing.jaeger.samplingServerURL=http://localhost:5778/sampling
      - --tracing.jaeger.samplingType=const
      - --tracing.jaeger.samplingParam=1.0
      - --tracing.jaeger.traceContextHeaderName=uber-trace-id
      - --tracing.jaeger.collector.endpoint=http://jaeger-collector:14268/api/traces?format=jaeger.thrift

    ports:
      - "80:80"
      - "443:443"
      - "8080:8080" # The Web UI (enabled by --api.insecure=true)

    labels:
      #
      - "traefik.enable=true"
      - "traefik.docker.network=nucnuc"
      # Dashboard
      - "traefik.http.routers.traefik.rule=Host(`traefik.gxxxs.page`)"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.tls.certresolver=leresolver"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.middlewares=usersfile@file"
# - "traefik.http.routers.traefik.middlewares=forwardAuth"
 
      # Global Redirect to https
      - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=websecure"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"

      # Middleware Redirect
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"

      # Authentication
      #- "traefik.http.middlewares.authtraefik.basicauth.users=user:your htaccess password cipher" # user/password"

      # Certificate name and san
      - "traefik.http.routers.traefik.tls.certresolver=basic"
      - "traefik.http.routers.traefik.tls.domains[0].main=gxxxs.page"
      - "traefik.http.routers.traefik.tls.domains[0].sans=*.gxxxs.page"

    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - "./letsencrypt:/letsencrypt"
      - "./conf:/conf"
    
    environment:
      - CF_API_EMAIL=<your cloudflare email address>
      - CF_DNS_API_TOKEN=<your cloudflare api token>
      - CF_ZONE_API_TOKEN=<your cloudflare api token>

# #
  whoami:
    # A container that exposes an API to show its IP address
    image: containous/whoami
# networks:
# - nucnuc

    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=nucnuc"

      - "traefik.http.routers.whoami.rule=Host(`whoami.gxxxs.page`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"

      - "traefik.http.routers.whoami.tls=true"
      - "traefik.http.routers.whoami.tls.certresolver=basic"
      - "traefik.http.routers.whoami.tls.domains[0].main=gxxxs.page"
      - "traefik.http.routers.whoami.tls.domains[0].sans=*.gxxxs.page"
# - "traefik.http.routers.whoami.tls.certresolver=le"
# - "traefik.http.routers.whoami.tls.certificates.certFile=/letsencrypt"

      - "traefik.http.routers.whoami.middlewares=usersfile@file"      
# - "traefik.http.middlewares.authtraefik.basicauth.users=user:your htaccess password cipher" # user/password

```

regards  
Steve

---

<div class="post-metadata">

**Author:** ![ldez](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/ldez/32/5_2.png) [@ldez](https://community.traefik.io/u/ldez)\
**Post date:** [February 18, 2020, 4:39pm UTC](https://community.traefik.io/t/docker-dynamic-labels-when-not-using-swarm/4480/4 "2020-02-18T16:39:02Z")

</div>

> [@stevegroom](#):
>
> Should the port be the internal port or the published port ?

Should be the internal port (80)

> [@stevegroom](#):
>
> But I think that is expected

Yes it's expected and right.

---

<div class="post-metadata">

**Author:** ![stevegroom](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/stevegroom/32/1696_2.png) [@stevegroom](https://community.traefik.io/u/stevegroom)\
**Post date:** [February 21, 2020, 2:52pm UTC](https://community.traefik.io/t/docker-dynamic-labels-when-not-using-swarm/4480/5 "2020-02-21T14:52:08Z")

</div>

@Idez, thanks for the pointers. I managed to get it working in the end.

One thing that was throwing me was that the service names used in docker-compose have to be unique across the docker-machine.

I had two different solutions using service web and eventually spotted that the Traefik router on one solution was actually invoking the web service on the other. I now have it working, but don't feel this is the best solution as I would like to reuse docker-compose files as templates in several projects.

regards  
Steve
