Search code examples
dockerdocker-composetraefik

How to mae Traefik as reverse-proxy with docker-compose?


I have docker-compose build with symfony on apache and angular on nginx. It is possible that more docker-compositions can be run, so now I want to make my own DNS using traefik - I want to set hostname of each app, make docker-compose up and resolve apps with hostname when they are ready.

Traefik docker-compose:

version: '3.1'

networks:
  proxy:
    external: true
  internal:
    external: false

services:
  traefik:
    image: traefik:v2.1
    command: --api.insecure=true --providers.docker
    labels:
      - traefik.frontend.rule=Host:monitor.docker.localhost
      - traefik.port=8080
    networks:
      - proxy
    ports:
      - 80:80
      - 8080:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Apps docker-compose:

# Run docker-compose build
# Run docker-compose up
# Live long and prosper

version: '3.1'
networks:
  proxy:
   external: true
  internal:
   external: false
services:
    apache:
        build: .docker/apache
        container_name: sf4_apache
        volumes:
          - .docker/config/vhosts:/etc/apache2/sites-enabled
          - ./backend:/home/wwwroot/sf4
        depends_on:
          - php
        labels:
          - traefik.http.routers.sf4_apache.rule=Host(`symfony.docker.localhost`)
          - traefik.http.services.apache.loadbalancer.server.port=80
        networks:
         - internal
         - proxy   

    php:
        build: .docker/php
        container_name: sf4_php
        volumes:
          - ./backend:/home/wwwroot/sf4
          - ./executor:/home/wwwroot/pipe
        networks:
         - internal
        labels:
         - traefik.enable=false  


    nginx:
      container_name: angular_nginx
      build: .docker/nginx
      volumes:
        - ./frontend/dist/frontend:/usr/share/nginx/html
      ports:
        - "81:80"
        - "443:443"
      labels:
        - traefik.http.routers.angular_nginx.rule=Host(`angular.docker.localhost`)
      networks:
        - internal
        - proxy     
    node:
        build: .docker/node
        container_name: angular_node
        ports:
            - 4200:4200
        volumes:
            - ./frontend:/home/node/app/frontend
        tty: true
        command:
            - /bin/sh
            - -c
            - |
                cd /home/node/app/frontend && npm start
        expose:
            - "4200"   
        networks:
         - internal
        labels:
         - traefik.enable=false     

Can't make it work: sometimes I get Bad Gateway at domains (symfony.docker.localhost), sometimes it crushed because both servers using one port, so please help me to run this correctly


Solution

  • First, docker frontend and backend are deprecated in version 2.1 check this link

    here is an example of doing the same in traefik 2.1

    version: '3.7'
    
    networks:
      traefik:
        external: true
    
    volumes:
      db_data:
    
    services:
    
      proxy:
        image: traefik:v2.1
        command:
          - '--providers.docker=true'
          - '--entryPoints.web.address=:80'
          - '--providers.providersThrottleDuration=2s'
          - '--providers.docker.watch=true'
          - '--providers.docker.swarmMode=true'
          - '--providers.docker.swarmModeRefreshSeconds=15s'
          - '--providers.docker.exposedbydefault=false'
          - '--providers.docker.defaultRule=Host("local.me")'
          - '--accessLog.bufferingSize=0'
          - '--api=true'
          - '--api.dashboard=true'
          - '--api.insecure=true'
          - '--ping.entryPoint=web'
        volumes:
          - '/var/run/docker.sock:/var/run/docker.sock:ro'
        ports:
          - '80:80'
          - '8080:8080'
        deploy:
          restart_policy:
            condition: any
            delay: 5s
            max_attempts: 3
            window: 120s
          update_config:
            delay: 10s
            order: start-first
            parallelism: 1
          rollback_config:
            parallelism: 0
            order: stop-first
        logging:
          driver: json-file
          options:
            'max-size': '10m'
            'max-file': '5'
        networks:
          - traefik
    
      mysql:
        image: mysql:5.7
        command: mysqld --general-log=1 --general-log-file=/var/log/mysql/general-log.log
        deploy:
          restart_policy:
            condition: any
            delay: 5s
            max_attempts: 3
            window: 120s
          update_config:
            delay: 10s
            order: start-first
            parallelism: 1
          rollback_config:
            parallelism: 0
            order: stop-first
        logging:
          driver: json-file
          options:
            'max-size': '10m'
            'max-file': '5'
        networks:
          - traefik
        volumes:
          - db_data:/var/lib/mysql
        environment:
          MYSQL_ROOT_PASSWORD: dummy
          MYSQL_DATABASE: rails_blog_production
    
      rails_blog_web:
        image: wshihadeh/rails_blog:demo-v1
        command: 'web'
        deploy:
          labels:
            - traefik.enable=true
            - traefik.http.services.blog.loadbalancer.server.port=8080
            - traefik.http.routers.blog.rule=Host(`blog.local.me`)
            - traefik.http.routers.blog.service=blog
            - traefik.http.routers.blog.entrypoints=web
            - traefik.docker.network=traefik
          restart_policy:
            condition: any
            delay: 5s
            max_attempts: 3
            window: 120s
          update_config:
            delay: 10s
            order: start-first
            parallelism: 1
          rollback_config:
            parallelism: 0
            order: stop-first
        logging:
          driver: json-file
          options:
            'max-size': '10m'
            'max-file': '5'
        networks:
          - traefik
        depends_on:
          - mysql
        environment:
          DATABASE_URL: mysql2://root:dummy@mysql/rails_blog_production
          RAILS_SERVE_STATIC_FILES: 'true'
    

    for more information, you can check this blog post