Traefik loadbalancing to several apps using config file

Hi everyone,

My goal is to set-up Traefik (with static and dynamic configuration files) to load balance incoming traffic to several web applications. In the future I would also want to spin-up new web applications automatically on the fly so I want to have docker-compose files separated for the each application.

For now I just want to understand how the whole thing works so I'm using "whoami" containers to mimic my web-applications. I was able to configure my Traefik dashboard on https and to redirect www to non-www.

The problem is that I get "404 page not found" accessing whoami.mydomain.com page. However both : http -> https and www -> non-www work with whoami.mydomain.com. I can also see the "whoami" container in the traefik dashboard (see screenshot):

Other questions

  1. How should I do to add a second "whoami" container listening on an other port. I tried to pass the command - --port=81 but it still gives me "80/tcp" if I do a "docker ps" command. Is it the expected behavior ? However if I change the port, I do see the change in traefik dashboard in the server url (it is not shown in the screenshot above though).
  2. Do you recommend using configuration files (for static and dynamic configurations) or using labels in docker-compose ? Is there a preferred method for what I'm planing to do or it does not make difference ?

I have looked at traefik simple exemple but I'm not able to have it done in my way.
Thank you in advance for your help

Here is my code:

docker-traefik.yml

# @prettier
version: "3.3"
networks:
  proxy:
    name: proxy
    external: true
volumes:
  letsencrypt:
    name: letsencrypt
services:
  traefik:
    image: traefik:v3.2
    networks:
      - proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./letsencrypt:/letsencrypt
      - ./config:/etc/traefik/config
      - ./logs:/var/log
      - ./traefik.yml:/etc/traefik/traefik.yml:ro
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    restart: unless-stopped
  
  # whoami:
  #   image: traefik/whoami:v1.10
  #   networks:
  #     - proxy

traefik.yml (static configuration)

## STATIC CONFIGURATION
global:
  checkNewVersion: false
  sendAnonymousUsage: false
################################################################
# Traefik Logging
################################################################
log:
  level: DEBUG
  format: common
  filepath: /var/log/traefik.log
accesslog:
  format: DEBUG
  filepath: /var/log/traefik-access.log
################################################################
# API and dashboard configuration
################################################################
api:
  insecure: false
  dashboard: true
################################################################
# Docker configuration backend
################################################################
providers:
  docker:
    watch: true
    exposedByDefault: false
    endpoint: "unix:///var/run/docker.sock"
    network: proxy
  file:
    directory: /etc/traefik/config
    watch: true
################################################################
# Entrypoint
################################################################
entryPoints:
  web:
    address: :80
    http:
      redirections:
        entrypoint:
          to: websecure
          scheme: https
  websecure:
    address: :443
    http:
      middlewares:
        - no-www@file
################################################################
# Challenge TLS
################################################################
certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@mydomain.com
      storage: /letsencrypt/acme.json
      tlsChallenge: {}```

dynamic.yml (dynamic configuration)

http: 
  routers:
    api:
      rule: Host(`traefik.mydomain.com`) || Host(`www.traefik.mydomain.com`)
      middlewares: 
        - auth
      service: api@internal
      entryPoints: 
        - "websecure"
      tls:
        certResolver: "letsencrypt"
  middlewares:
    auth:
      basicAuth:
        users : 
          - "user:hashedpassword"
    no-www:
      redirectRegex:
        regex: "^https?://www\\.(.*)"
        replacement: "https://${1}"
        permanent: true

docker-whoami.yml

services:
  whoami:
    image: traefik/whoami:v1.10
    networks:
      - proxy
    labels:
      - traefik.enable=true
      - traefik.http.routers.mywhoami.rule=Host(`whoami.mydomain.com`) || Host(`www.whoami.mydomain.com`)
      - traefik.http.services.mywhoami.loadbalancer.server.port=80
      - traefik.http.routers.mywhoami.entrypoints=websecure
networks:
  proxy:
    name: proxy

If you want to dynamically spin up services, you should use Traefik Docker configuration discovery with labels.

Place everything inside containers, which share a common Docker network. No need for ports. Make sure to use different router and service names in the labels.

Check simple Traefik example.

Thank you for your answer and you advice ! I do have checked your example, which helped me a lot to understand.

As you have suggested I have created the router and service for this container, the same way you did in your example. When I start the whoami container, I can see that the router and service is added to the traefik dashboard, but still I cannot access the page ("404 page not found").

      - traefik.enable=true
      - traefik.http.routers.mywhoami.rule=Host(`whoami.mydomain.com`) || Host(`www.whoami.mydomain.com`)
      - traefik.http.routers.mywhoami.service=mywhoami
      - traefik.http.services.mywhoami.loadbalancer.server.port=80
      - traefik.http.routers.mywhoami.entrypoints=websecure

I solved it. The following labels worked. I needed to had TLS:

      - traefik.enable=true
      - traefik.http.routers.mywhoami.tls=true
      - traefik.http.routers.mywhoami.tls.certresolver=letsencrypt
      - traefik.http.routers.mywhoami.rule=Host(`whoami.mydomain.com`) || Host(`www.whoami.mydomain.com`)
      # - traefik.http.services.mywhoami.loadbalancer.server.port=80
      - traefik.http.routers.mywhoami.entrypoints=websecure

You should enable TLS globally on the entrypoint, as in the example.