Search code examples
dockernetwork-programmingdocker-composetraefik

How to use internal networks with Traefik 2.x?


I'm trying to setup a simple Nextcloud Stack with docker-compose and Traefik.

Here is my docker-compose.yml

version: '3.7'
services:
  nextcloud-database:
    image: mariadb
    container_name: nextcloud-database
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    restart: always
    volumes:
      - $PWD/db:/var/lib/mysql
    env_file:
      - db.env
    networks:
      - backend
    logging:
      options:
        max-size: '12m'
        max-file: '5'
      driver: json-file

  nextcloud-redis:
    image: redis:alpine
    container_name: nextcloud-redis
    restart: always
    networks:
      - backend

  nextcloud-cron:
    image: nextcloud:latest
    container_name: nextcloud-cron
    restart: always
    volumes:
      - $PWD/cloud:/var/www/html
    entrypoint: /cron.sh
    networks:
      - backend

  nextcloud-app:
    image: nextcloud:latest
    container_name: nextcloud-app
    restart: always
    volumes:
      - $PWD/config:/var/www/html/config
      - $PWD/cloud:/var/www/html
      - $PWD/apps:/var/www/html/apps
      - $PWD/data:/var/www/html/data
    environment:
      - NEXTCLOUD_DATA_DIR=/var/www/html/data
      - MYSQL_HOST=nextcloud-database
    env_file:
      - db.env
    depends_on:
      - nextcloud-database
      - nextcloud-redis
      - nextcloud-cron
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud.entrypoints=http"
      - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.blablubb.de`)"
      - "traefik.http.middlewares.nextcloud-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.nextcloud.middlewares=nextcloud-https-redirect"
      - "traefik.http.routers.nextcloud-secure.entrypoints=https"
      - "traefik.http.routers.nextcloud-secure.rule=Host(`nextcloud.blablubb.de`)"
      - "traefik.http.routers.nextcloud-secure.tls=true"
      - "traefik.http.routers.nextcloud-secure.tls.certresolver=http"
      - "traefik.http.routers.nextcloud-secure.service=nextcloud"
      - "traefik.http.services.nextcloud.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"
    networks:
      - proxy
      - backend
    logging:
      options:
        max-size: '12m'
        max-file: '5'
      driver: json-file

networks:
  proxy: # this is the network provided by traefik
    external: true
  backend:
    external: false

and the db.env

MYSQL_PASSWORD="waff"
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
MYSQL_ROOT_PASSWORD="waff"

The Nextcloud instance is reachable via the domain nextcloud.blablubb.de. So my question: What's needed that my nextcloud-docker container can communicate with each other? I thought it's handled through the backend network, but I've always error message, f.e. nextcloud-mysql isn't reachable.

Without Treafik this setup is working fine.

Thank you guys.


Solution

  • if you want two containers to be able to communicate with each other you need to have an overlay network and add both of the containers to the same network like

    docker network create --driver=overlay --subnet=10.0.15.0/24  --attachable traefik
    
        networks:
          - backend
    

    which is the case in your docker-compose file, here is an example for doing this

    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'
        volumes:
          - '/var/run/docker.sock:/var/run/docker.sock:ro'
        ports:
          - '80:80'
        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'
    

    one thing that is missing in your configurations is the linking between the services. For instance, you are providing the MySQL host in the application server but the port is missing.