====== Using "Traefik" for Reverse Proxy and "Let's Encrypt" for Automatic HTTPS certificates ======
===== Important Note : =====
This is an alternative method to [[engineering:computer_science:docker:application_guides:docker_nginx_reverse_proxy|Using Nginx as a Reverse Proxy]].
===== Purpose: =====
The purpose of using Traefik are:
* Prevent having to restart the [[engineering:computer_science:docker:application_guides:docker_nginx_reverse_proxy|nginx Reverse-Proxy Container]] everytime we want to test a new / deploy a new service.
* Ease of Escalability - We will be able to scale our infrastructure faster, since we don't have to manage HTTPS Certificates for every subdomain
* Keep the services so that, they are individuals service, but working though a central distributor. This could also be done with a [[engineering:computer_science:docker:application_guides:docker_nginx_reverse_proxy|nginx Reverse-Proxy Container]] but since we will have an WebUI, it will be easier to troubleshoot instead of having to SSH into the Host.
===== Create the Folder and Config Files =====
* Change the Path under "STORAGE_PATH" to match your environment.
#!/bin/bash
STORAGE_PATH="/home/docker-user/traefik"
mkdir -p "$STORAGE_PATH"/storage/traefik/data
touch "$STORAGE_PATH"/storage/traefik/data/acme.json
chmod 600 "$STORAGE_PATH"/storage/traefik/data/acme.json
touch "$STORAGE_PATH"/storage/traefik/data/traefik.yml
===== Deploy the Traefik configuration =====
* Change "email: email@example.com" to your Email address.
nano 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
===== Create the traefik docker-compose.yml =====
* Change the "traefik.example.com" to your own "sub.domain.tld"
* Create a USER:PASSWORD combo for "[…]users=USER:PASSWORD" with
echo $(htpasswd -nb ) | sed -e s/\\$/\\$\\$/g
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
- ./storage/traefik/data/traefik.yml:/traefik.yml:ro
- ./storage/traefik/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
"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
===== Adding Services to Traefik =====
Start the traefik container - docker-compose up -d
Change your docker-compose.yml from other services to be available via Traefik.
As example, here is my docker-compose.yml for DokuWiki before and after Traefik.
**Before**
version: '3'
volumes:
dokuwiki_data:
external: true
dokuwiki_conf:
external: true
dokuwiki_lib-plugins:
external: true
dokuwiki_lib-tpl:
external: true
dokuwiki_logs:
external: true
services:
dokuwiki:
image: 'mprasil/dokuwiki'
container_name: 'dokuwiki_zebra'
ports:
- '80:80'
volumes:
- dokuwiki_data:/dokuwiki/data
- dokuwiki_conf:/dokuwiki/conf
- dokuwiki_lib-plugins:/dokuwiki/lib/plugins
- dokuwiki_lib-tpl:/dokuwiki/lib/tpl
- dokuwiki_logs:/var/log
**After**
* You can uncomment the "ports:" so, if you start just that container, it will be reachable over your domain.tld. Sometimes it is usefull for troubleshooting
* Add the "labels". You have/should replace [...].dokuwiki.[...] with the name of the service, so it is easier to identify on the Traefik WebUI
* Don't forget to change the "rule=Host" and "[...]-secure.rule=Host" to your "sub.domain.tld"
* Don't forget to change the ".server.port" to the Port where the Service is listening
* For complex services (for example Wordpress + MySQL), add an extra network, for eg. "wordpress_network" so the MySQL instant is only reachable via the Wordpress Service, and not over the Proxy configuration
version: '3'
volumes:
dokuwiki_data:
external: true
dokuwiki_conf:
external: true
dokuwiki_lib-plugins:
external: true
dokuwiki_lib-tpl:
external: true
dokuwiki_logs:
external: true
services:
dokuwiki:
image: 'mprasil/dokuwiki'
container_name: 'dokuwiki'
restart: unless-stopped
networks:
- proxy
#ports:
# - '80:80'
volumes:
- dokuwiki_data:/dokuwiki/data
- dokuwiki_conf:/dokuwiki/conf
- dokuwiki_lib-plugins:/dokuwiki/lib/plugins
- dokuwiki_lib-tpl:/dokuwiki/lib/tpl
- dokuwiki_logs:/var/log
labels:
- "traefik.enable=true"
- "traefik.http.routers.dokuwiki.entrypoints=http"
- "traefik.http.routers.dokuwiki.rule=Host(`wiki.carlossousa.tech`)"
- "traefik.http.middlewares.dokuwiki-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.dokuwiki.middlewares=dokuwiki-https-redirect"
- "traefik.http.routers.dokuwiki-secure.entrypoints=https"
- "traefik.http.routers.dokuwiki-secure.rule=Host(`wiki.carlossousa.tech`)"
- "traefik.http.routers.dokuwiki-secure.tls=true"
- "traefik.http.routers.dokuwiki-secure.tls.certresolver=http"
- "traefik.http.routers.dokuwiki-secure.service=dokuwiki"
- "traefik.http.services.dokuwiki.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
After starting the service, it should now be available.