Multinetwork with Traefik and docker-compose

In this post I will show you how to connect multiple docker-compose files in different networks with traefik as a reverse proxy

.Sometimes kubernetes is just to much for a small project and you find yourself creating a good old docker-compose file. This time it’s about a simple wordpress setup but with in mind that we might add later more services like another wordpress page on the same VM. This brings in a proxy so we are able to route traffic incoming to port 80/443 to different services (wordpress instances). As a second requirement we want to handle the different services in separate docker-compose files and last but not least we want SSL via Let’s Encrypt.

Prerequisites

  • docker-compose
  • A sub-/domain you can point to a VM with a public IP so Let’s Encrypt can do it’s magic

Traefik

Traefik is an easy to use proxy with docker in mind starting from day one. It was the first proxy I am aware of which reacts on docker labels for service discovery. It comes with a nice UI and supports Let’s Encrypt.

Create a directory named traefik and put the following docker-compose.yaml inside it:

version: '3.8'
services:
  proxy:
    image: traefik:v2.3
    logging:
        driver: "json-file"
        options:
            max-file: "5"
            max-size: "10m"
    command:
      - --providers.docker
      - --log.level=DEBUG
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entrypoints.web.http.redirections.entrypoint.scheme=https
      - --api.dashboard=true
      - --api.insecure=true
      - --certificatesresolvers.le.acme.email=yourmail@example.com
      - --certificatesresolvers.le.acme.storage=/acme/acme.json
      - --certificatesresolvers.le.acme.tlschallenge=true
    ports:
      - "80:80"
      - "443:443"
      # traefik webui
      - 8080:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      # feel free to mount it somewhere else
      - /mnt/traefik/acme:/acme
    restart:
      always
    networks:
    - traefik

networks:
  traefik:
    name: traefik-net

With a docker-compose up we tell treafik to do the following:

  • enable the docker provider
  • set log level to debug for easy debugging
  • don’t add every docker service to traefik
  • listen on port 80 and port 443 with the (free to choose) entrypoint names web and websecure
  • redirect http traffic to https
  • enable the dashboard in the insecure mode (for production you should use the secure mode)
  • configure Let’s encrypt
  • listen to docker.sock for service discovery
  • use a volume to store Let’s encrypt certs (acme.json)
  • create a docker network named traefik-net

That last one is essential when we want to join the traefik network with other services in different docker-compose files.

Check the dashboard by visiting http://yourserver:8080/dashboard/

Nice! The dashboard shows up with our named entrypoints.

WordPress

Create another directory named wordpress with the following docker-compose.yaml

version: '3.8'
services:
  db:
    image: 'mariadb:10.5.8'
    logging:
        driver: "json-file"
        options:
            max-file: "5"
            max-size: "10m"
    volumes:
      - '/mnt/mysql:/var/lib/mysql'
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 'verysecure'
      MYSQL_DATABASE: wordpress
      MYSQL_USER: 'wordpress-user'
      MYSQL_PASSWORD: 'secureme'
    networks:
     - backend

  wordpress:
    image: wordpress:5.6.0
    logging:
        driver: "json-file"
        options:
            max-file: "5"
            max-size: "10m"
    restart:
      always
    volumes:
      - /mnt/wordpress:/var/www/html
    environment:
      WORDPRESS_ADMIN_PASSWORD: 'againsecure'
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: 'wordpress-user'
      WORDPRESS_DB_PASSWORD: 'secureme'
      WORDPRESS_DB_NAME: wordpress
    labels:
      - traefik.enable=true
      - traefik.http.routers.wordpress.rule=Host(`mypage.de`)
      - traefik.http.routers.wordpress.entrypoints=websecure
      - traefik.http.routers.wordpress.tls.certresolver=le
      - traefik.docker.network=traefik-net
    depends_on:
      - db
    networks:
      - backend
      - web

networks:
  web:
    external:
      name: traefik-net
  backend:

In general this is a straight forword docker-compose.yaml for wordpress so I will only explain the traefik and network parts. At line 39 we start defining labels which will picked up by traefik.

traefik.enable=true

Because we used providers.docker.exposedbydefault=false the mysql service will be ignored and this label tells traefik to take care off the wordpress service.

traefik.http.routers.wordpress.rule=Host(mypage.de)

Configures a router named “wordpress” to listen for requests with the host header “mypage.de”.

traefik.http.routers.wordpress.entrypoints=websecure

The wordpress router should listen to the named entrypoint “websecure” which means port 443 in our case.

traefik.http.routers.wordpress.tls.certresolver=le

Use the TLS challenge configured in “le” to generate and renew ACME certificates.

traefik.docker.network=traefik-net

Tell traefik to use “traefik-net” as the network to route requests to this service.

networks:
  - backend
  - web

Put the wordpress service in a network named “backend” so it can speak to mysql and in a network named “web”.

networks:
  web:
    external:
      name: traefik-net
  backend:

Defines the network “web” which points to an external network with the name “traefik-net”. We created “traefik-net” in the first docker-compose.yaml and now we join it with our wordpress service. This is important to allow communication between traefik and our wordpress service. Last but not least we create a regular docker network “backend” where the service mysql and wordpress can talk to each other.

Fire it up with docker-compose up and check the routers section in the traefik dashboard.

Our router “wordpress@docker” should show up . The suffix “@docker” is assigned by traefik for every docker router.

Point your browser to https://mypage.de and the wordpress installation page should show up.

You can now create more docker-compose.yaml files with another wordpress setup or anything else routed by traefik. Just check that you defined the needed traefik lables and you joined the “treafik-net” network so traefik can reach your service.