====== 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.