Traefik 2.0 + Docker: A Simple Step by Step Guide
Introduction
In this tutorial we will go trough the following things:
- Setup and configure Traefik in a Docker container
- Let’s Encrypt setup for automatic HTTPS certificates
- Deploy a simple service (Portainer) and expose it to the internet
You will find all the required configuration files in our Git repository.
Prerequisites
In order to follow along, you need these things:
- Docker (obviously)
- Docker Compose
- A domain
- Ports 80 and 443 forwarded to your Docker host
Setup and configure Traefik with Let’s Encrypt
Let’s get started by setting up Traefik.
First, create a directory for our containers:
mkdir -p /opt/containers/{traefik,portainer}
Create the data folder and config files for Traefik:
mkdir -p /opt/containers/traefik/data
touch /opt/containers/traefik/data/acme.json
chmod 600 /opt/containers/traefik/data/acme.json
touch /opt/containers/traefik/data/traefik.yml
The acme.json
file is the storage file for the HTTPS certificates.
Now we create the basic Traefik configuration file (/opt/containers/traefik/data/traefik.yml
):
api:
dashboard: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
http:
acme:
email: email@example.com
storage: acme.json
httpChallenge:
entryPoint: http
Please change the email
address for the certificatesresolvers at line 18.
Here is the Docker Compose file for Traefik (/opt/containers/traefik/docker-compose.yml
):
version: "3"
services:
traefik:
image: traefik:v2.0
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./data/acme.json:/acme.json
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
- "traefik.http.middlewares.traefik-auth.basicauth.users=USER:PASSWORD"
- "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.certresolver=http"
- "traefik.http.routers.traefik-secure.service=api@internal"
networks:
proxy:
external: true
Using this compose file, Traefik will also expose a dashboard (line 32). Please change the host rule at line 23 and 28 to your subdomain.
In addition, change the credentials at line 24. Those credentials must be in htpasswd format.
To generate htpasswd credentials, you can use the following command (change <USER>
and <PASSWORD>
):
echo $(htpasswd -nb <USER> <PASSWORD>) | sed -e s/\\$/\\$\\$/g
Once that’s done we can create the proxy network an fire up Traefik:
docker network create proxy
cd /opt/containers/traefik
docker-compose up -d
Visit traefik.example.com
and enjoy the new dashboard.
Deploy Portainer
Here is the Docker Compose file for Portainer (/opt/containers/portainer/docker-compose.yml
):
version: "3"
services:
portainer:
image: portainer/portainer:latest
container_name: portainer
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.entrypoints=http"
- "traefik.http.routers.portainer.rule=Host(`portainer.example.com`)"
- "traefik.http.middlewares.portainer-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.portainer.middlewares=portainer-https-redirect"
- "traefik.http.routers.portainer-secure.entrypoints=https"
- "traefik.http.routers.portainer-secure.rule=Host(`portainer.example.com`)"
- "traefik.http.routers.portainer-secure.tls=true"
- "traefik.http.routers.portainer-secure.tls.certresolver=http"
- "traefik.http.routers.portainer-secure.service=portainer"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
Again, change the subdomain portainer.example.com at line 18 and 22.
Fire up Portainer:
cd /opt/containers/portainer
docker-compose up -d
You can now visit Portainer by browsing to portainer.example.com
.