about summary refs log tree commit diff
path: root/bundles/traefik
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2025-09-07 17:32:13 +0200
committerRobert Günzler <r@gnzler.io>2025-09-07 17:42:42 +0200
commit38be6c13f76e893cf47636257071b440dec0c5b2 (patch)
treef7ded3235a7e3362cbd1ed3d91523968fe0faf90 /bundles/traefik
initial commit
Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to 'bundles/traefik')
-rw-r--r--bundles/traefik/files/kube.yaml146
-rw-r--r--bundles/traefik/files/logrotate.conf10
-rw-r--r--bundles/traefik/files/secret.yaml6
-rw-r--r--bundles/traefik/files/tls-redirect.yaml6
-rw-r--r--bundles/traefik/items.py15
-rw-r--r--bundles/traefik/metadata.py8
6 files changed, 191 insertions, 0 deletions
diff --git a/bundles/traefik/files/kube.yaml b/bundles/traefik/files/kube.yaml
new file mode 100644
index 0000000..5c2298a
--- /dev/null
+++ b/bundles/traefik/files/kube.yaml
@@ -0,0 +1,146 @@
+# TODO: how to handle services going away (e.g. during update/backup)
+apiVersion: v1
+kind: Pod
+metadata:
+  name: traefik
+  labels:
+    traefik.enable: true
+    traefik.http.routers.traefik-metrics.entrypoints: metrics
+    traefik.http.routers.traefik-metrics.rule: Path(`/metrics/traefik`)
+    traefik.http.routers.traefik-metrics.middlewares: replacepath-bare
+    traefik.http.routers.traefik-metrics.service: prometheus@internal
+    # common middleware
+    ## metrics
+    traefik.http.middlewares.replacepath-bare.replacepath.path: /
+    traefik.http.middlewares.replacepath-metrics.replacepath.path: /metrics
+    ## authelia
+    traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader: true
+    traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders: Remote-User,Remote-Groups,Remote-Email,Remote-Name
+% if node.name == "inazuma":
+    traefik.http.middlewares.authelia.forwardAuth.address: http://authelia:9091/api/authz/forward-auth
+% elif node.name == "shimakaze":
+    traefik.http.middlewares.authelia.forwardAuth.address: http://inazuma:9091/api/authz/forward-auth
+% endif
+% if node.name == "inazuma--TODO":
+    ## tsauth
+    traefik.http.middlewares.tsauth.forwardAuth.trustForwardHeader: true
+    traefik.http.middlewares.tsauth.forwardAuth.authResponseHeaders: ^Tailscale-
+    traefik.http.middlewares.tsauth.forwardAuth.address: http://localhost:3000
+% endif
+spec:
+  restartPolicy: Never
+  dnsPolicy: Default
+  containers:
+    - name: traefik
+      image: docker.io/library/traefik:v3.4.3
+      args:
+        - --log.level=info
+        - --accesslog=true
+        - --accesslog.format=json
+        - --accesslog.filepath=/data/access.log
+        - --accesslog.bufferingsize=0
+        - --accesslog.fields.headers.defaultmode=drop
+        - --accesslog.fields.headers.names.User-Agent=keep
+        - --api.dashboard=true
+        - --api.insecure=true
+        - --metrics.prometheus=true
+        - --metrics.prometheus.manualrouting=true
+        # providers
+        - --providers.file.directory=/etc/traefik
+        - --providers.file.watch=true
+        - --providers.docker=true
+        - --providers.docker.exposedByDefault=false
+        # entrypoints
+        - --entrypoints.metrics.address=:9010
+        - --entrypoints.traefik.address=:4000
+        - --entrypoints.http.address=:80
+        - --entrypoints.https.address=:443
+        # certs
+        - --certificatesresolvers.le.acme.email=r+acme@gnzler.io
+        - --certificatesresolvers.le.acme.storage=/data/acme.json
+        # - --certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
+        # http challenge doesn't work for tailscale endpoints
+        # - --certificatesresolvers.le.acme.httpchallenge.entrypoint=http
+        - --certificatesresolvers.le.acme.dnschallenge.provider=cloudflare
+        - --certificatesresolvers.ts.tailscale=true
+      envFrom:
+        - secretRef:
+            name: traefik
+      volumeMounts:
+        - name: traefik-data
+          mountPath: /data
+        - name: traefik-file-provider
+          mountPath: /etc/traefik
+          readOnly: true
+        - mountPath: /var/run/docker.sock:z
+          name: podmansock
+          readOnly: true
+        - mountPath: /var/run/tailscale/tailscaled.sock:z
+          name: tailscaledsock
+      ports:
+        - containerPort: 80
+          hostPort: 80
+          protocol: TCP
+        - containerPort: 443
+          hostPort: 443
+          protocol: TCP
+        - containerPort: 4000
+          hostPort: 4000
+          protocol: TCP
+        - containerPort: 9010
+          hostPort: 9010
+          protocol: TCP
+
+      # TODO: investigate, not useful on it's own because:
+      #       httpGet translates to a curl invocation inside the container, puts
+      #       a requirement on the container
+      #       https://github.com/containers/podman/blob/v4.8.3/pkg/specgen/generate/kube/kube.go#L647
+
+      # livenessProbe:
+      #   httpGet:
+      #     path: /ping # needs --ping=true
+      #     port: 4000
+      #   initialDelaySeconds: 2
+      #   periodSeconds: 20
+      resources:
+        limits:
+          cpu: 1000m
+          memory: 512Mi
+        requests:
+          cpu: 10m
+          memory: 75Mi
+% if node.name == "inazuma--TODO":
+    - name: tsauth
+      image: docker.io/library/busybox:stable-uclibc
+      command:
+        - /tsauth
+      volumeMounts:
+        - name: tsauthbin
+          mountPath: /tsauth
+          readOnly: true
+        - mountPath: /var/run/tailscale/tailscaled.sock:z
+          name: tailscaledsock
+% endif
+  volumes:
+  - name: traefik-data
+    hostPath:
+      path: /var/lib/traefik
+      type: DirectoryOrCreate
+  - name: traefik-file-provider
+    hostPath:
+      path: /etc/traefik
+      type: DirectoryOrCreate
+  - name: podmansock
+    hostPath:
+      path: /run/podman/podman.sock
+      type: File
+  - name: tailscaledsock
+    hostPath:
+      path: /run/tailscale/tailscaled.sock
+      type: File
+% if node.name == "inazuma--TODO":
+  - name: tsauthbin
+    hostPath:
+      path: /home/robert/tsauth
+      type: File
+% endif
diff --git a/bundles/traefik/files/logrotate.conf b/bundles/traefik/files/logrotate.conf
new file mode 100644
index 0000000..5e3a71a
--- /dev/null
+++ b/bundles/traefik/files/logrotate.conf
@@ -0,0 +1,10 @@
+/var/lib/traefik/*.log {
+	weekly
+	rotate 2
+	size 50M
+	missingok
+	notifempty
+	postrotate
+	  podman pod kill --signal="USR1" traefik
+	endscript
+}
diff --git a/bundles/traefik/files/secret.yaml b/bundles/traefik/files/secret.yaml
new file mode 100644
index 0000000..d702d51
--- /dev/null
+++ b/bundles/traefik/files/secret.yaml
@@ -0,0 +1,6 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: traefik
+data:
+  CLOUDFLARE_DNS_API_TOKEN: ${repo.libs.util.base64(repo.vault.cmd(f"rbw get cloudflare/letsencrypt"))}
diff --git a/bundles/traefik/files/tls-redirect.yaml b/bundles/traefik/files/tls-redirect.yaml
new file mode 100644
index 0000000..fc494c2
--- /dev/null
+++ b/bundles/traefik/files/tls-redirect.yaml
@@ -0,0 +1,6 @@
+http:
+  middlewares:
+    tls-redirect:
+      redirectScheme:
+        scheme: https
+        permanent: false
diff --git a/bundles/traefik/items.py b/bundles/traefik/items.py
new file mode 100644
index 0000000..9ed76aa
--- /dev/null
+++ b/bundles/traefik/items.py
@@ -0,0 +1,15 @@
+files = {
+    "/etc/deployments/traefik/kube.yaml": {
+        "content_type": "mako",
+        "triggers": {"svc_s6rc:traefik:restart"},
+    },
+    "/etc/deployments/traefik/secret.yaml": {
+        "content_type": "mako",
+        "mode": "0600",
+        "triggers": {"svc_s6rc:traefik:restart"},
+    },
+    "/etc/traefik/tls-redirect.yaml": {},
+    "/etc/logrotate.d/traefik": {
+        "source": "logrotate.conf",
+    },
+}
diff --git a/bundles/traefik/metadata.py b/bundles/traefik/metadata.py
new file mode 100644
index 0000000..e90f053
--- /dev/null
+++ b/bundles/traefik/metadata.py
@@ -0,0 +1,8 @@
+defaults = {
+    "containers": {
+        "traefik": {},
+    },
+    "metrics": {
+        "traefik": {},
+    },
+}