loading...
Cover image for How to have HTTPs on development with Docker, Traefik v2 and mkcert

How to have HTTPs on development with Docker, Traefik v2 and mkcert

nflamel profile image Fran C. Updated on ・3 min read

Docker is cool

I've discovered Docker recently. I know... it's been there for a while, but I've never added it to my workflow until very recently and I'm quite happy with the solutions it gives me to the problems I have. I'm still a newbie with it and enjoying a lot what I'm learning.

One of the things I like about Docker is that it allows me to carry the stack definition I want for my project between different computers and reduces a lot the amount of effort I need to setup my dev env when I'm playing with some side projects.

This article is meant for Docker newbies like myself who need to solve this fairly common web development problem.

HTTPs and domain names in development are important

Making sure that your development environment looks similar to your production one is important. It helps reducing unexpected issues when going live.

I've used nginx in the past for this and it is still a very solid solution. But in development and just for a simple development reverse proxy I prefer to use traefik these days. Mainly because it works pretty well with Docker.

In addition to that, to simply generate signed certificates in development I use mkcert, which is super simple to use. Many also propose and use Let's Encrypt and traefik itself has some support for it, but we won't use in this example.

Stop it already! what do I need?

  • You need an application of some sort. Ours is going to be ruby -run -e httpd . -p 3000 which is a server showing the current folder's contents. Note as well that I don't run my apps inside Docker itself during development. I don't do it because I run things like linters, test suites, etc from my editor and running the app inside Docker is usually a barrier for that.

    If you run the app inside docker check the traefik documentation because having this same proxy in your case is even easier!

  • You need Docker running on your machine.

  • Some way to resolve the domain you want to your app. In my case I just add the domain I need to my /etc/hosts but you might prefer other solutions like using dnsmasq.

The config!

  1. You need something like this in your docker-compose.yml.

    You don't need to have only that. I typically declare other stuff there like databases or other infrastructure pieces that I need in development.

  2. This is the static configuration for traefik.

  3. And this is the dynamic one, which defines the routing between the different parts.

  4. Last but not least you need to install mkcert and run it to generate a couple of mock certs for you. What I usually do is that I keep a devcerts folder in my projects that I ignore. And then I generate a new cert on each new dev machine. In this case with:

    mkcert mkcert my-app.com "*.my-app.com"
    

    To have *.my-app.com available.

    Note however that you could avoid that by using Let's Encrypt, but I've not needed it, so I don't use it.

  5. Put it all together! This is how I organize the code in this example:

    example
    ├── devcerts
    │   ├── my-app.com+1-key.pem
    │   └── my-app.com+1.pem
    ├── docker-compose.yml
    ├── traefik.config.toml
    └── traefik.toml
    
    
  6. Run your app (ruby -run -e httpd . -p 3000 or whatever your app incantation is!)

  7. Run docker-compose up and see the magic happen!

You can now go go http://my-app.com and see how you're automatically redirected to https://my-app.com and have your app working there :D

Remember to check http://my-app.com:8080 to see traefik's dashboard.

Finally kudos to my mate gtrias for showing me what I can do with Docker!

(Spoiler, he's on dev.to too!)

gtrias image


Posted on by:

nflamel profile

Fran C.

@nflamel

I break code for a living... wait no, I fix it, most of the times. Well, sometimes.Yeah, I break code for a living.

Discussion

markdown guide