In this Guide we will install Traefik v2 as a reverse proxy with free LetsEncrypt SSL certificates for our Docker container. With Traefik you will be able to run multiple containers with different domains. This guide offers a ready to use docker-compose.yml
for a quick start with Traefik.
Traefik v2 Install
Preparation
Info
If you don’t have docker installed yet, you can find instructions for Ubuntu or Debian. This Guide uses docker-compose to run Traefik, therefore its necessary to also install docker-compose. The two linked guides will help you to setup docker-compose on your own host.
Frist we create a few files and folders to work with. I like my docker setup to be clean and easy, therefore I create a folder for each docker-compose Stack I’m running on my host.
mkdir -p /opt/containers/traefik
mkdir /opt/containers/traefik/data
touch /opt/containers/traefik/data/traefik.yml
touch /opt/containers/traefik/data/acme.json
chmod 600 /opt/containers/traefik/data/acme.json
To create password protected sites, like our Traefik Dasboard, you will need to install apache2-utils which provides the handy htpasswd
tool we are using in this Guide.
apt-get install apache2-utils
traefik.yml
Next we open our newly created traefik config file with an editor of your choice.
vim /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 protected] # CHANGE HERE
storage: acme.json
httpChallenge:
entryPoint: http
You need to replace the example email with your own email address. This email address is used to request our free LetsEncrypt SSL certificates.
In this Guide we are enabling the Traefik Dashboard. This Dashboard is helpful to check if a service is running correct or not. If you are not interested to run Trafik with the Dashboard enabled, you can set dashboard: false
. I would suggest to leave the Dashboard running, if you are new to Traefik.
docker-compose.yml
version: '3'
services:
traefik:
image: traefik:latest
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.domain.tld`)"
- "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.domain.tld`)"
- "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
With our docker-compose.yml we are defining the Traefik docker container with all the settings and config files. To get Traefik up and running you only need to adjust some settings:
- replace both
traefik.domain.tld
with your own domain name. This domain should be a subdomain like traefik.ae3.ch for example. Later you will be able access Traefik Dasboard with this (sub)domain. - replace
USER:PASSWORD
with your own credentials.
You will not be able to write your password as it is, you first need to generate a hash of your password, like so:
echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
Replace user
and password
with your own credentials you would like to use for Traefik Dashboard.
Output should look like this:
user:$$apr1$$zUb/YuK2$$57psQ0U71DlfdHPr0yoHe/
Now you can copy the whole line of your own output and replace the USER:PASSWORD
with your own credentials:
# before
- "traefik.http.middlewares.traefik-auth.basicauth.users=USER:PASSWORD"
# after
- "traefik.http.middlewares.traefik-auth.basicauth.users=user:$$apr1$$zUb/YuK2$$57psQ0U71DlfdHPr0yoHe/"
Create Docker Network for Traefik
It’s a good idea to setup a separate docker network that is used by Traefik and all other docker containers you would like to make available by Traefik.
To create this docker network, all you need to do is paste the following command into your CLI:
docker network create proxy
Run Traefik
Now we are ready to run our traefik container. Make sure you are located inside the /opt/containers/traefik
directory and then simply run:
docker-compose up -d
After a few seconds you can check and access your Traefik Dashboard at your custom Domain you entered in your docker-compose.yml (example: traefik.ae3.ch). When you try to visit the Dasboard, you should be prompted by a login form, there you enter your username and password you defined earlier.
Traefik will automatically generate SSL certificates for all domains you are connecting to Traefik. All certificates are also renewed automatically, this means you don’t need to do any manual steps to secure your website with SSL, isn’t it fancy huh? :)
Use your container with Traefik
To access your own containers with your domain, you need to add some config labels to your existing docker-compose.yml file of your other containers. This is an example config, you could use with any docker container you are running.
service-name:
labels:
- "traefik.enable=true"
## replace `service-name` with the name of your docker container, you will need to replace this entry in all lines
- "traefik.http.routers.service-name.entrypoints=http"
## replace `example.domain.tld` with your own domain name, for example `wordpress.domain.ch`
- "traefik.http.routers.service-name.rule=Host(`example.domain.tld`)"
- "traefik.http.middlewares.service-name-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.service-name.middlewares=service-name-https-redirect"
- "traefik.http.routers.service-name-secure.entrypoints=https"
## replace `example.domain.tld` with your own domain name, for example `wordpress.domain.ch`
- "traefik.http.routers.service-name-secure.rule=Host(`example.domain.tld`)"
- "traefik.http.routers.service-name-secure.tls=true"
- "traefik.http.routers.service-name-secure.tls.certresolver=http"
## replace `service-name` with the name of your docker container
- "traefik.http.routers.service-name-secure.service=service-name"
## if your container is using a different port then `80`, just replace this port with your custom one, for example: `8888`
- "traefik.http.services.service-name.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
Make sure your container has the same docker network assignes as traefik has. You can do this by adding the following to your docker-compose.yml
service-name:
networks:
- proxy
networks:
proxy:
external: true
WordPress docker-compose.yml for Traefik
A complete docker-compose.yml
for WordPress could look like this:
version: '3.1'
services:
wordpress:
image: wordpress
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- wordpress:/var/www/html
labels:
- "traefik.enable=true"
- "traefik.http.routers.wordpress.entrypoints=http"
- "traefik.http.routers.wordpress.rule=Host(`wordpress.domain.ch`)"
- "traefik.http.middlewares.wordpress-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.wordpress.middlewares=wordpress-https-redirect"
- "traefik.http.routers.wordpress-secure.entrypoints=https"
- "traefik.http.routers.wordpress-secure.rule=Host(`wordpress.domain.ch`)"
- "traefik.http.routers.wordpress-secure.tls=true"
- "traefik.http.routers.wordpress-secure.tls.certresolver=http"
- "traefik.http.routers.wordpress-secure.service=wordpress"
- "traefik.http.services.wordpress.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
networks:
- proxy
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
volumes:
wordpress:
db:
networks:
proxy:
external: true