From 8b09cf55a2f2a0d17858bae9e786c8d4a98f4d6b Mon Sep 17 00:00:00 2001
From: Jens Langhammer <jens.langhammer@beryju.org>
Date: Sun, 18 Oct 2020 18:46:13 +0200
Subject: [PATCH] root: upgrade to traefik 2.3

---
 docker-compose.yml                            | 36 +++++++++++--------
 docs/upgrading/to-0.12.md                     |  7 +++-
 helm/templates/web-deployment.yaml            |  4 +--
 .../providers/proxy/controllers/docker.py     | 11 ++++--
 passbook/root/asgi.py                         |  4 +--
 5 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/docker-compose.yml b/docker-compose.yml
index bc646312c..3ce0f9c88 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -12,16 +12,12 @@ services:
       - POSTGRES_PASSWORD=${PG_PASS:-thisisnotagoodpassword}
       - POSTGRES_USER=passbook
       - POSTGRES_DB=passbook
-    labels:
-      - traefik.enable=false
     env_file:
       - .env
   redis:
     image: redis
     networks:
       - internal
-    labels:
-      - traefik.enable=false
   server:
     image: beryju/passbook:${PASSBOOK_TAG:-0.11.0-stable}
     command: server
@@ -34,9 +30,13 @@ services:
     networks:
       - internal
     labels:
-      - traefik.port=8000
-      - traefik.docker.network=internal
-      - traefik.frontend.rule=PathPrefix:/
+      traefik.enable: 'true'
+      traefik.docker.network: internal
+      traefik.http.routers.app-router.rule: PathPrefix(`/`)
+      traefik.http.routers.app-router.service: app-service
+      traefik.http.routers.app-router.tls: 'true'
+      traefik.http.services.app-service.loadbalancer.healthcheck.hostname: passbook-healthcheck-host
+      traefik.http.services.app-service.loadbalancer.server.port: '8000'
     env_file:
       - .env
   worker:
@@ -44,8 +44,6 @@ services:
     command: worker
     networks:
       - internal
-    labels:
-      - traefik.enable=false
     environment:
       PASSBOOK_REDIS__HOST: redis
       PASSBOOK_POSTGRESQL__HOST: postgresql
@@ -60,12 +58,22 @@ services:
     networks:
       - internal
     labels:
-      - traefik.frontend.rule=PathPrefix:/static, /robots.txt, /favicon.ico
-      - traefik.port=80
-      - traefik.docker.network=internal
+      traefik.enable: 'true'
+      traefik.docker.network: internal
+      traefik.http.routers.static-router.rule: PathPrefix(`/static`, `/robots.txt`, `/favicon.ico`)
+      traefik.http.routers.static-router.tls: 'true'
+      traefik.http.routers.static-router.service: static-service
+      traefik.http.services.static-service.loadbalancer.healthcheck.path: /
+      traefik.http.services.static-service.loadbalancer.server.port: '80'
   traefik:
-    image: traefik:1.7
-    command: --api --docker --defaultentrypoints=https --entryPoints='Name:http Address::80 Redirect.EntryPoint:https' --entryPoints='Name:https Address::443 TLS'
+    image: traefik:2.3
+    command:
+      - "--accesslog=true"
+      - "--api.insecure=true"
+      - "--providers.docker=true"
+      - "--providers.docker.exposedbydefault=false"
+      - "--entrypoints.http.address=:80"
+      - "--entrypoints.https.address=:443"
     volumes:
       - /var/run/docker.sock:/var/run/docker.sock:ro
     ports:
diff --git a/docs/upgrading/to-0.12.md b/docs/upgrading/to-0.12.md
index 55830cd99..5fd8e8a79 100644
--- a/docs/upgrading/to-0.12.md
+++ b/docs/upgrading/to-0.12.md
@@ -8,6 +8,7 @@ This update brings these headline features:
 - Alerts now disappear automatically
 - Audit Logs are now searchable
 - Users can now create their own Tokens to access the API
+- docker-compose deployment now uses traefik 2.3
 
 Fixes:
 
@@ -15,7 +16,11 @@ Fixes:
 
 ## Upgrading
 
-Docker-compose users can upgrade just as usual.
+### docker-compose
+
+Docker-compose users should download the latest docker-compose file. This includes the new traefik 2.3.
+
+### Kubernetes
 
 For Kubernetes users, there are some changes to the helm values.
 
diff --git a/helm/templates/web-deployment.yaml b/helm/templates/web-deployment.yaml
index 783f41456..20f89bc9b 100644
--- a/helm/templates/web-deployment.yaml
+++ b/helm/templates/web-deployment.yaml
@@ -100,14 +100,14 @@ spec:
               port: http
               httpHeaders:
                 - name: Host
-                  value: kubernetes-healthcheck-host
+                  value: passbook-healthcheck-host
           readinessProbe:
             httpGet:
               path: /
               port: http
               httpHeaders:
                 - name: Host
-                  value: kubernetes-healthcheck-host
+                  value: passbook-healthcheck-host
           resources:
             requests:
               cpu: 100m
diff --git a/passbook/providers/proxy/controllers/docker.py b/passbook/providers/proxy/controllers/docker.py
index d31ef8025..cbcf06cdc 100644
--- a/passbook/providers/proxy/controllers/docker.py
+++ b/passbook/providers/proxy/controllers/docker.py
@@ -22,8 +22,13 @@ class ProxyDockerController(DockerController):
         for proxy_provider in ProxyProvider.objects.filter(outpost__in=[self.outpost]):
             proxy_provider: ProxyProvider
             external_host_name = urlparse(proxy_provider.external_host)
-            hosts.append(external_host_name)
+            hosts.append(f"`{external_host_name}`")
+        traefik_name = f"pb-outpost-{self.outpost.pk.hex}"
         return {
-            "traefik.frontend.rule": f"Host:{','.join(hosts)}",
-            "traefik.port": "4180",
+            "traefik.enable": "true",
+            f"traefik.http.routers.{traefik_name}-router.rule": f"Host({','.join(hosts)})",
+            f"traefik.http.routers.{traefik_name}-router.tls": "true",
+            f"traefik.http.routers.{traefik_name}-router.service": f"{traefik_name}-service",
+            f"traefik.http.services.{traefik_name}-service.loadbalancer.healthcheck.path": "/",
+            f"traefik.http.services.{traefik_name}-service.loadbalancer.server.port": "4180",
         }
diff --git a/passbook/root/asgi.py b/passbook/root/asgi.py
index fc5347d9c..fa37a7e17 100644
--- a/passbook/root/asgi.py
+++ b/passbook/root/asgi.py
@@ -88,8 +88,8 @@ class ASGILogger:
                 self.log(runtime)
             await send(message)
 
-        if self.headers.get(b"host", b"") == b"kubernetes-healthcheck-host":
-            # Don't log kubernetes health/readiness requests
+        if self.headers.get(b"host", b"") == b"passbook-healthcheck-host":
+            # Don't log healthcheck/readiness requests
             await send({"type": "http.response.start", "status": 204, "headers": []})
             await send({"type": "http.response.body", "body": ""})
             return