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: 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:
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.
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=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