So first of all, why HTTPS? I only have a blog with static content right? Correct! But there are two main reasons why you’d want HTTPS even for a site with only static content. First of all; with plain HTTP anyone between your server and the client can insert information in transit. So an Internet Service Provider could if they wanted insert their own advertisements. You think ISP’s won’t do that? Think again! Yes; I was just as appalled as you are right now.
My Traefik Deployment
Traefik fortunately supports the free Let’s Encrypt certificates out of the box. All that is needed for Let’s Encrypt is an e-mail address and you 'proving' that you own a domain by providing some content on it. Traefik handles this last bit for you, however there are some caveats.
What went wrong
The way this 'proof' works is that Let’s Encrypt does a request to your domain over HTTP. This makes sense since you’re setting up a new domain; there is no HTTPS certificate yet so it can’t reach your server (Traefik). So don’t enable forwards from HTTP to HTTPS yet!
What also went wrong for me initially was that my docker-compose files had hosts rules like "blog.localhost", "jenkins.localhost", etc. Since Traefik doesn’t understand that these should not have certificates it failed on trying to get certs for these. So I had to change the
docker-compose.yml files for a few services to remove the localhost entries, so to take my blog for example I had to change it from this:
labels: - "traefik.backend=blog" - "traefik.frontend.rule=Host: blog.localhost, niels.nu, www.niels.nu" - "traefik.port=80"
labels: - "traefik.backend=blog" - "traefik.frontend.rule=Host: niels.nu, www.niels.nu" - "traefik.port=80"
So since you need to configure Let’s Encrypt in your Traefik config file (
traefik.toml) I had to change my deployment a bit. So this is my .toml file:
defaultEntryPoints = ["http", "https"] [web] address = ":8080" [entryPoints] [entryPoints.http] address = ":80" #[entryPoints.http.redirect] #entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] [acme] email = "email@example.com" storage = "acme.json" entryPoint = "https" onDemand = false OnHostRule = true
You can see that this config has the HTTP to HTTPS redirect disabled. I had to disable this to make sure that the verification from Let’s Encrypt to my domain would work.
I created a simple
Dockerfile to add
traefik.toml to the image:
FROM traefik ADD traefik.toml . EXPOSE 80 EXPOSE 8080 EXPOSE 443
And slightly changed my
docker-compose.yml to use this
Dockerfile instead of just pulling the image:
version: '2' services: proxy: build: . restart: always command: --web --docker --logLevel=DEBUG networks: - webgateway ports: - "80:80" - "443:443" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock networks: webgateway: driver: bridge
I then deployed the new Treafik instance with
docker-compose up -d --build (the --build was added to force Docker compose to always rebuild the container from the
When I check the logs on the Treafik container I now get this output:
time="2017-02-25T11:48:20Z" level=debug msg="Challenge GetCertificate niels.nu" time="2017-02-25T11:48:20Z" level=debug msg="ACME got domain cert niels.nu"
And voila; my blog is now reachable on https://niels.nu !
I certainly put off enabling HTTPS long enough! I really like how Traefik does all the heavy lifting for me. The only main issues I had were having a HTTP to HTTPS redirect enabled and having some 'invalid' public domains in the docker-compose files for my applications.