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.
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: trueBecause traefik is an external network provided by the Traefik service, it is declared as such. My blog web app consists of multiple Docker services:
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=falseAs 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=falseThe interesting part, however, are the settings of the web app.
My web app has the following Traefik requirements:
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=traefikWe now just only have to connect it to the traefik and blog network like so:
networks:
      - traefik
      - blogAnd 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