Traefik and Docker-Compose
In this post, i will explain a real usecase i had with a customer. The purpose was to add https to their existing website (already running with Docker). Easy (for my part) but a part of the demand was to have only one docker-compose file for both dev and production (dev is made on developpers’ machines).
First attempt : differents files
My first attempt was to create differents config files for traefik. Everything works fine but as already stated, this is not very compliant with the customer’s request.
The solution : use environment variables
The way i choose for this problem is to use the fact that docker-compose can use a .env file (doc). The next step has been to variabilize all my config.
Here is the final config file (stripped down for the only usefull parts) :
version: 3.3
services:
lb:
image: traefik:1.5-alpine
restart: always
command: --web --acme.storage=/etc/traefik/acme.json --logLevel=info \
${TRAEFIK_ENTRYPOINT_HTTP} ${TRAEFIK_ENTRYPOINT_HTTPS}\
--defaultentrypoints=${TRAEFIK_DEFAULT_ENTRYPOINTS} \
--acme=${ACME_ENABLE} --acme.entrypoint=https --acme.httpchallenge --acme.httpchallenge.entrypoint=http \
--acme.domains="${ACME_DOMAINS}" --acme.email="${ACME_EMAIL}" \
--docker --docker.domain="${DOCKER_DOMAIN}" --docker.endpoint="unix:///var/run/docker.sock" \
--docker.watch=true --docker.exposedbydefault="false"
container_name: traefik
networks:
- core
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- ./docker/traefik:/etc/traefik/
- /var/run/docker.sock:/var/run/docker.sock
web:
image: "customer/nginx"
container_name: web
depends_on:
- php
networks:
- core
volumes:
- ./src/:/var/www/
labels:
- "traefik.backend=nginx"
- "traefik.frontend.rule=Host:${TRAEFIK_HOST}"
- "traefik.port=80"
- "traefik.enable=true"
The variables used are :
- TRAEFIK_ENTRYPOINT_HTTP : define the http entryPoint
- TRAEFIK_ENTRYPOINT_HTTPS : define the https entryPoint
- TRAEFIK_DEFAULT_ENTRYPOINTS : define the default entryPoints
- TRAEFIK_HOST : the Host rule for Traefik
- ACME_ENABLE : true or false
- ACME_DOMAINS : the domains to use for Let’s Encrypt
- ACME_EMAIL : the email to use for Let’s Encrypt
- DOCKER_DOMAIN : default domain used
And now you will just have to create a .env file :
-
Dev .env file:
ACME_ENABLE=false ACME_EMAIL=xxx@domain.tld ACME_DOMAINS=domain.tld,www.domain.tld DOCKER_DOMAIN="dev.domain" TRAEFIK_DEFAULT_ENTRYPOINTS=http TRAEFIK_ENTRYPOINT_HTTP=--entryPoints="Name:http Address::80" TRAEFIK_ENTRYPOINT_HTTPS= TRAEFIK_HOST=domain.local,www.domain.local
-
Production .env file
ACME_ENABLE=true ACME_EMAIL=xxx@domain.tld ACME_DOMAINS=domain.tld,www.domain.tld DOCKER_DOMAIN="prod.domain" TRAEFIK_DEFAULT_ENTRYPOINTS=http,https TRAEFIK_ENTRYPOINT_HTTP=--entryPoints="Name:http Address::80" TRAEFIK_ENTRYPOINT_HTTPS=--entryPoints="Name:https Address::443 TLS TRAEFIK_HOST=domain.tld,www.domain.tld
And that’s all !