In a previous post I mentioned I recently migrated from Nginx to Traefik. There I presented my Traefik Docker service spun up with docker-compose.

However, that was only the first part of the migration. The second part consists of updating the docker-compose.yml file of my web services, such as this blog.

Mind bowingly easy: just connect to the Traefik network & set a few Docker labels

All it actually took was to connect my existing service to the Traefik network and extend the existing docker-compose.yml by a few Docker labels.

Note: in the previous post the Traefik service uses a Docker network called "Traefik". So in the docker-compose.yml of my blog web app, I appended the following the networks section:

networks:
  traefik:
    external: true
  blog:
    internal: true

Because traefik is an external network provided by the Traefik service, it is declared as such. My blog web app consists of multiple Docker services:

  • postgres
  • redis
  • elasticsearch
  • blog: the actual blog web app that runs Wagtail (a Python CMS built on top of Django).

For these services to communicate with each other, I specified an internal network named blog.

Because the postgres, redis and elasticsearch service will only be used internally by our web app, we disable Traefik on them and connect them only to the blog network. So I added the following sections to each of these services:

networks:
      - blog
    labels:
      - traefik.enable=false

As an example, the elasticsearch service looks as following:

elasticsearch:
    container_name: elasticsearch
    image: elasticsearch:2.3
    restart: unless-stopped
    expose:
      - "9200"
    volumes:
      - esdata:/usr/share/elasticsearch/data
    networks:
      - blog
    labels:
      - traefik.enable=false

The interesting part, however, are the settings of the web app.

The actual Traefik configuration of your web app with Docker labels

My web app has the following Traefik requirements:

  • connect to the traefik network
  • listen to a specific host, i.e. www.apoehlmann.com
  • use TLS with automatic certificate generation (we use letsecrypt for that)
  • make it listen only to web secure https requests
  • redirect all http request on www.apoehlmann.com to port 8000 of the container, because that's where our Wagtail (Django) app listens

This can be all achieved with the following 6 labels:

labels:
      - traefik.http.routers.web.rule=Host(`www.apoehlmann.com`)
      - traefik.http.routers.web.tls=true
      - traefik.http.routers.web.tls.certresolver=le
      - traefik.http.routers.web.entrypoints=websecure
      - traefik.port=8000
      - traefik.docker.network=traefik

We now just only have to connect it to the traefik and blog network like so:

networks:
      - traefik
      - blog

And that's it!

Traefik automatically knows now there's a new Docker service that wants to use TLS and all https requests at www.apoehlmann.com redirected to its port 8000. Traefik will take care not only of those wishes but also of the whole letsencrypt certificate generation (and its renewal in the future!).

So the whole docker-compose service of my blog web app looks as following

blog:
    container_name: blog
    environment:
      DATABASE_URL: postgres://user:pw@postgres/blog_db
      CACHE_URL: redis://redis
      ELASTICSEARCH_ENDPOINT: elasticsearch
    build:
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - .:/code
      - /var/backups/blog/logs:/logs
    ports:
      - "8000:8000"
    networks:
      - trafik
      - blog
    depends_on:
      - postgres
      - redis
      - elasticsearch
    labels:
      - traefik.http.routers.web.rule=Host(`www.apoehlmann.com`)
      - traefik.http.routers.web.tls=true
      - traefik.http.routers.web.tls.certresolver=le
      - traefik.http.routers.web.entrypoints=websecure
      - traefik.port=8000
      - traefik.docker.network=traefik
Getagged mit:
Docker Traefik
blog comments powered by Disqus