Expose a Docker container without labels

Hi there,
just a quick question, is it possible to expose a Docker container without the use of the labels inside the docker-compose file?

Here are my labels:

      - traefik.enable=true
      - traefik.http.routers.container_name.rule=Host(`...`)
      - traefik.http.routers.container_name.entrypoints=https
      - traefik.http.routers.container_name.tls.certresolver=letsencrypt
      - traefik.http.routers.container_name.service=container_name
      - traefik.http.services.container_name.loadbalancer.server.port=8080

I want to change this configuration and use only the dynamic_conf.yml (or TOML) file.

I've already tried that, but Traefik doesn't recognize the Docker container as a Docker service (container_name@docker) but as a file service (container_name@file).

Is there anything wrong with what I do or the only way to expose a Docker container is now through the use of labels?

Thank tou!

in service_name@docker and service_name@file what you have on the right side of @ is not a service but configuration provider. If you provide configuration via docker labels then it's @docker if you provide it via dynamic_conf.yml (or TOML) file, then it's @file

Sorry, I was wrong to write, the concept of provider is clear to me, my question is then this: it is possible to expose a Docker container through the dynamic_conf.yml file or the only way to do it is to insert the labels directly in the docker-compose .yml file?

Sure. What seems to be the problem?

There is nothing wrong with that, but I had misunderstood then, I thought I could centralize everything in the dynamic_conf.yml file and leave the docker-compose.yml without traefik stuff.

But you can. What I asked you above is what seems to be the problem with that?

My guess is that you tried, saw some error or unexpeted behaviour and mis-interpreted it. But unless you say what it is, it's very difficult to help.

Caveat: you can centralize dymaic configuration there which is not to be mixed with static configuration But in practical sense that should be what you are after anyway. You do not have to use docker-compose and you do not have to use labels.

Hello, I'm on the same question,

how can we use Docker provider without label ?

I would like something like :

[http.services.adminer]
  [http.services.adminer.loadbalancer.server]
    port = 8080

[http.routers.adminer]
  rule = "Host(`dev.localhost`) && PathPrefix(`/adminer`)"
  entrypoints = ["web"]
  service = "adminer"

how can i bind it to my docker service dynamically without to much labels ?
someone would have an example maybe?

thank you

edit : is it a good practice?

Hello,

here is dynamic configuration reference for the file provider. You can use that instead of labels.

In your example you will need instead of specifying service port specify service url.

The disadvantage is of course since you are not using docker provider (which is label based) you will not have the automatic discovery.

What problem are you trying to solve? Everything fits to respective purpose. Docker labels with docker is probably the most convenient way working with docker, because of the discovery. However sometimes it's convenient to control traefik externally. While API achieves that, it is not persisted, so the File Provider is the best bet then. Obviously, it's most useful when your services/backends are outside of the docker instance that hosts traefik.

To use Docker without labels, you will to known the IP and the port of your container.

[http.services.adminer]
  [http.services.adminer.loadbalancer.server]
    url = http://<the-container-IP>:<port>

[http.routers.adminer]
  rule = "Host(`dev.localhost`) && PathPrefix(`/adminer`)"
  entrypoints = ["web"]
  service = "adminer"

There are 3 main problems with that:

  1. the container IP is dynamic
  2. the container need to expose port
  3. Traefik cannot discover the new containers or the changes.
  1. As the IP is dynamic, if a container restart the application provided by the container will be unavailable.
  2. The fact to expose the ports of the containers is not a good practice and can produce some security issues.
  3. If Traefik cannot detect new containers, you lost the most important things of Traefik: the automatic discovery and the automatic update.

So I strongly advise against doing this, whether in terms of stability or security.

The file provider has been made for the old infrastructures, based on VM or server manually managed, so I cannot recommend to use it for define routers and services for containers.

You can use it (the file provider) to define middlewares, some TLS things, and in this case it's a good idea.

3 Likes

@ldez I don't have any reference to documentation hand to back this up, but if memory serves me well it does not have to be ip address. If you are on the same docker network (as traefik) you can address your container by name (and port). Also in this case you do not have to expose the port on the non-traefik container.

This largely mitigates poits 1 and 2 at the bottom of your post. 3 though still stands and is a very strong reason to prefer labels.

Example:

docker-compose.yaml
version: "3.3"
services:
  traefik:
    image: "traefik:v2.0.0"
    container_name: "traefik"
    command:
      - --entryPoints.web.address=:80
      - --providers.file.filename=/dyn.toml
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./dyn.toml:/dyn.toml"
  whoami:
    image: "containous/whoami"
    container_name: "whoami"
dyn.toml
[http.routers.main]
entryPoints = ["web"]
service = "main"
rule = "PathPrefix(`/`)"

[http.services.main.loadBalancer]
passHostHeader = true
[[http.services.main.loadBalancer.servers]]
url = "http://whoami"

@zespri @ldez thanks for your help, I understand better now :slight_smile: