Docker + Traefik: A Love Story
Docker is an amazing tool on its own, but setting up a reverse proxy with Apache or Nginx to route requests to specific containers is a nightmare. The problem is Docker will not assign the same ip address to a container across restarts.
The Problem
Docker is an amazing tool on its own, but setting up a reverse proxy with Apache or Nginx to route requests to specific containers is a nightmare. The problem is Docker will not assign the same ip address to a container across restarts.
The Solution
So how can we configure a reverse proxy without static ip addresses? That's where traefik comes in. Traefik is a web server, just like Apache or Nginx, but its bread and butter is its ability to connect to the docker socket to dynamically generate a reverse proxy configuration.
The Setup
You'll need to have Docker and docker-compose installed if you want to follow along. First we need to create an external Docker network which traefik and our exposed applications can talk to each other. Create a network named web with the command docker network create web.
docker-compose.yml
version: '2'
services:
traefik:
image: traefik:1.5
restart: always
ports:
- 80:80
- 443:443
- 8080:8080
networks:
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
- ./acme.json:/acme.json
container_name: traefik
networks:
web:
external: true
Here's a breakdown of what the previous docker-compose file does:
- Create a container which runs Traefik version 1.5
- Always restart the traefik container if it goes down
- Map your machine's ports 80, 443, and 8080 to the container
- Exist inside the web network we created earlier
- Mount your machine's docker socket into the container to allow dynamic configuration
- Mount a configuration file to control traefik behaviour
- Mount a JSON file to store SSL information
- Name the container traefik
traefik.toml
debug = false
checkNewVersion = true
logLevel = "ERROR"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[retry]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "example.com"
watch = true
exposedbydefault = false
[web]
address = ":8080"
[acme]
email = "email@example.com"
storage = "acme.json"
entryPoint = "https"
OnHostRule = true
[accessLog]
This configuration uses the docker socket to gather information from containers. It creates a web dashboard available at localhost:8080 and automatically generates valid SSL certificates via LetsEncrypt. In this configuration all http requests are redirected to https.
In the same directory create a new file named acme.json with the command touch acme.json.
Configure Application Containers
Traefik uses Docker labels specified on each container to control routes and backends.
This docker-compose file creates a webserver accessible at fileserver.example.com. Container specific configuration labels can be found here.
version: '2'
services:
fileserver:
image: nginx
restart: always
expose:
- 80
labels:
- "traefik.port=80"
- "traefik.frontend.rule=Host:fileserver.example.com"
- "traefik.backend=fileserver"
- "traefik.docker.network=web"
- "traefik.enable=true"
networks:
default:
external:
name: web
The Conclusion
Once Traefik is set up, routing to your containerized applications is as simple as adding a few docker container labels and Traefik takes care of the rest.