Multiple nginx Container - Traefik switch between them

I have a docker Container for Traefik with network traefik, and three Containers in different Networks with use Traefik.

Nginx does not have a specific server_name (server_name _;), as I thought traefik redirects the data correctly according to the service name. Each nginx has its own network because there are several related containers (PHP, DB,...) in separate docker-compose.yml files.
I have defined specific name for each nginx, but traefik switch between them. I call domain1.test, and sometimes i get the content of domain2 or domain3.

What have I forgotten to configure to make it work?

Shorted docker compose:


  traefik:
    image: traefik:3.0
    container_name: traefi
    ports:
      - "80:80"
      - "443:443"
    networks:
      net_traefik:
        
  nginx-containetr1:
    build:
      ......
    container_name: nginx-container1
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.container1.rule=Host(`container1.test`) || Host(`www.container1.test`)"
      - "traefik.http.routers.container1.entrypoints=webSecure"
      - "traefik.http.routers.container1.tls=true"
      .....
      - "traefik.http.routers.container1.service=container1"
      - "traefik.http.services.container1.loadbalancer.server.port=80"
      - "traefik.docker.network=traefik"
    networks:
      - traefik
      - container1
        
  nginx-containetr1:
    build:
      ......
    container_name: nginx-container2
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.container2.rule=Host(`container2.test`) || Host(`www.container2.test`)"
      - "traefik.http.routers.container2.entrypoints=webSecure"
      - "traefik.http.routers.container2.tls=true"
      .....
      - "traefik.http.routers.container2.service=container2"
      - "traefik.http.services.container2.loadbalancer.server.port=80"
      - "traefik.docker.network=traefik"
    networks:
      - traefik
      - container2

Usually Traefik is pretty strict about the rules and Host() matching, we have never seen any issues, so it’s probably about your config.

Every service has their own name in labels, that looks good.

You declare docker.network, that’s great, too.

But it seems Traefik uses a different network than the target services.

You could centralize some settings in static config, reduce labels, compare to simple Traefik example.

Enable Traefik access log in JSON format to see more info about each request.

Maybe the mismatch happens within nginx.

I think so :smiley:

Correct. I use a Project with only contains Traefik, dnsmasq and step-ca for a main construct of development environment (or later productive without dnsmasq and step-ca).
Is this generally a problem if Traefik has a separate network?

Good Idea. Thank you. But I don't see any issues

{"ClientAddr":"192.168.65.1:51403","ClientHost":"192.168.65.1","ClientPort":"51403","ClientUsername":"-","DownstreamContentSize":90803,"DownstreamStatus":200,"Duration":188587125,"OriginContentSize":90803,"OriginDuration":188538458,"OriginStatus":200,"Overhead":48667,"RequestAddr":"container1.test","RequestContentSize":0,"RequestCount":4,"RequestHost":"container1.test","RequestMethod":"GET","RequestPath":"/login","RequestPort":"-","RequestProtocol":"HTTP/2.0","RequestScheme":"https","RetryAttempts":0,"RouterName":"container1@docker","ServiceAddr":"172.16.16.6:80","ServiceName":"container1@docker","ServiceURL":"http://172.16.16.6:80","StartLocal":"2024-05-08T07:19:54.777819543Z","StartUTC":"2024-05-08T07:19:54.777819543Z","TLSCipher":"TLS_AES_128_GCM_SHA256","TLSVersion":"1.3","entryPointName":"webSecure","level":"info","msg":"","time":"2024-05-08T07:19:54Z"}
{"ClientAddr":"192.168.65.1:51403","ClientHost":"192.168.65.1","ClientPort":"51403","ClientUsername":"-","DownstreamContentSize":80740,"DownstreamStatus":200,"Duration":181468416,"OriginContentSize":80740,"OriginDuration":181405584,"OriginStatus":200,"Overhead":62832,"RequestAddr":"container1.test","RequestContentSize":0,"RequestCount":5,"RequestHost":"container1.test","RequestMethod":"GET","RequestPath":"/login","RequestPort":"-","RequestProtocol":"HTTP/2.0","RequestScheme":"https","RetryAttempts":0,"RouterName":"container1@docker","ServiceAddr":"172.16.16.6:80","ServiceName":"container1@docker","ServiceURL":"http://172.16.16.6:80","StartLocal":"2024-05-08T07:19:58.49289067Z","StartUTC":"2024-05-08T07:19:58.49289067Z","TLSCipher":"TLS_AES_128_GCM_SHA256","TLSVersion":"1.3","entryPointName":"webSecure","level":"info","msg":"","time":"2024-05-08T07:19:58Z"}

Is it generally advisable to adapt the server_name to the host, or should this not be a problem for Traefik?

Edit: I think I found the problem, but I don't understand it at the moment.
Both php container called php and are in different networks. But also in the traefik network becase I need the dns. Both PHP response when i call the url. I use fast cgi with php:9000.
I think since both PHP containers are also on the Traefik network, both are responding because of the same name. I'll have to see if I can customize the names.
Or do you know a better solution?

One time the name is net_traefik and one time it’s traefik.

You should not need traefik Docker network for DNS.

Usually you would use the service name from compose to connect to other containers.

Maybe simplify your setup by using a php image with Apache included, then you don’t need 1-to-1 nginx and php for every target service.

php:<version>-apache

This image contains Debian's Apache httpd in conjunction with PHP (as mod_php) and uses mpm_prefork by default.

Zhis was an issue from shortening sorry :slight_smile:

The traefik Container has a additional dnsmasq Container to resolve test domain to traefik

I will check. Thank you

Hello!
I have the exact same problem here. Have you found a solution yet ?

My stack is the following:

  • One traefik in a "gateway" network
  • Two docker compositions with
    • One nginx in the "gateway" network and in the "app_xx" network
    • One php app in the "app_xx" network

My problem is that when I try to reach the nginx, it switches every two times between the two nginx. This is a problem as they don't have the same confs.

Have you used the same Traefik router and service name for the different services?

Thanks for your response.
I used a different router and service name.

My application docker-compose.yaml file looks like this:

networks:
  gateway:
    external: true  
  application:
    
  nginx:
    image: nginx:latest
    container_name: ${COMPOSE_PROJECT_NAME}_nginx
    networks:
      - application # <== This is the internal network
      - gateway # <== This is the traefik external network
    expose:
      - 80
    labels:
      - traefik.enable=true
      - traefik.http.routers.${COMPOSE_PROJECT_NAME}_home.rule=Host(`${COMPOSE_PROJECT_NAME}.${DOMAIN}`)
  
  service:
    #...
    # here is my php application

And in order to launch my compositions, I do:

docker compose -p project_name up -d 

So the router name is "project_name_home". And ${DOMAIN} is an environment variable

The problem is when when i launch two stacks, (project_name_1 and project_name_2), I reach the wrong nginx one time over two.

Do you have any idea ?

Did you check with docker inspect if the substitution was successful?

You only run a single Traefik instance across projects?

Which container do i need to inspect ?

Yes I only have one Traefik instance. It is supposed to redirect trafik to my different nginx containers

Edit: The nginx labels looks rignt:
"traefik.enable": "true",
"traefik.http.routers.test_home.rule": "Host(test.mydomain)"
"com.docker.compose.service": "nginx"

I think I might have found the issue. You don't set a Traefik service name per container, so Traefik needs to create one, and it's probably the container name. So you have two routers with different names, assigned to the same service name with two target containers.

Probably the simple solution: assign a unique service name, like in simple Traefik example:

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

Or use different names in compose file, not the same "nginx".