Search code examples
laraveldockerdocker-composetraefik

How to configure traefik to correctly route traffic from a specific domain to a specific nginx container


I have created two container laravel webapp (project1 and project2) with own nginx/php-fpm and linked them with traefik container. Each project has its own folder and docker-compose.yaml properly configured with traefik labels.

Thanks to traefik what I expect is that when I visit the project1.laravel.test I look at the contents of project1 and when I visit the project2.laravel.test I look at the content of project2.

The issue is that when I visit project1.laravel.test, alternately, the content of project1 is shown and other times the content of project2 is shown. If I shut down the container of the project2, project 1 works fine. It seems that traefik is configured as a load balancer but I don't understand where is the issue.

How to replicate my issue?


 1. git clone https://github.com/gtoto007/traefik-laravel-docker
 2. cd traefik-laravel-docker
 3. docker-compose -f traefik/docker-compose.yaml up -d
 4. docker-compose -f project1/docker-compose.yaml up -d
 5. docker-compose -f project1/docker-compose.yaml up -d

in your host file

127.0.0.1 traefik.laravel.test
127.0.0.1 project1.laravel.test
127.0.0.1 project2.laravel.test

MY DOCKER-COMPOSE FILES

Below for simplicity I put the three docker-compose of project1, project2 and traefik:

./traefik/docker-compose.yaml

version: "3.3"
networks:
  my-network:
    external: true

services:
  traefik:
    image: "traefik:v2.9"
    container_name: "traefik"
    networks:
      - my-network
    command:
      - "--api"
      - "--providers.docker.exposedbydefault=false"
      - "--api.insecure=true"
      - "--accesslog.filepath=/data/access.log"
      # entrypoints
      - "--entrypoints.http.address=:80"
      - "--entrypoints.https.address=:443"
      - "--entrypoints.traefik.address=:8888"
    ports:
      - "80:80"
      - "443:443"
      - "8888:8888"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.laravel.test`)"
      - "traefik.http.routers.traefik.entrypoints=traefik"

./project1/docker-compose.yaml

version: '3.8'

networks:
  my-network:
    external: true

services:
  nginx:
    build:
      dockerfile: docker/nginx/Dockerfile
      context: ./
    image: my-nginx
    volumes:
      - ./docker/nginx/conf.d:/etc/nginx/conf.d/
      - my-data_project1:/var/www
    networks:
      - my-network
    depends_on:
      - php-fpm
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.project1.rule=Host(`project1.laravel.test`)"
      - "traefik.docker.network=my-network"
  php-fpm:
    build:
      dockerfile: docker/php/Dockerfile
      context: ./
    image: my-php-fpm
    ports:
      - "5173:5173"
    volumes:
      - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
      - my-data_project1:/var/www
    networks:
      - my-network
  project1:
    build:
      dockerfile: docker/project1/Dockerfile
      context: ./
    image: project1:1.0
    volumes:
      - my-data_project1:/var/www
    networks:
      - my-network
volumes:
  my-data_project1:

./project2/docker-compose.yaml

version: '3.8'

networks:
  my-network:
    external: true

services:
  nginx:
    build:
      dockerfile: docker/nginx/Dockerfile
      context: ./
    image: my-nginx
    volumes:
      - ./docker/nginx/conf.d:/etc/nginx/conf.d/
      - my-data_project2:/var/www
    networks:
      - my-network
    depends_on:
      - php-fpm
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.project2.rule=Host(`project2.laravel.test`)"
      - "traefik.docker.network=my-network"
  php-fpm:
    build:
      dockerfile: docker/php/Dockerfile
      context: ./
    image: my-php-fpm
    ports:
      - "5174:5173"
    volumes:
      - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
      - my-data_project2:/var/www
    networks:
      - my-network
  project2:
    build:
      dockerfile: docker/project2/Dockerfile
      context: ./
    image: project2:1.0
    volumes:
      - my-data_project2:/var/www
    networks:
      - my-network
  #      - ./:/var/www
volumes:
  my-data_project2:

Solution

  • I resolved the issue. The problem is caused by container name conflict because the projects share the same network and some containers have the same hostname of default.

    For example, if you do a ping nginx sometimes you get the ip of the nginx service of project1 and other times you get the ip of the nginx service of project2 because both services use the same hostname.

    I fixed it by overwriting the hostnames for each container with unique hostname by Hostname property of docker-compose and corrected the nginx configuration for each project.

    You can watch my fixed in this commit : https://github.com/gtoto007/traefik-laravel-docker/commit/707925465b979168448128b8b307660bde2b5aeb