Add internal Traefik ingress for Pangolin and Authelia
This commit is contained in:
30
ingress/README.md
Normal file
30
ingress/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Ingress / Traefik
|
||||
|
||||
This stack adds an internal Traefik layer on PD.
|
||||
|
||||
Why this exists:
|
||||
- keep Pangolin as the public tunnel/edge from the VPS
|
||||
- centralize app routing behind one internal reverse proxy
|
||||
- put Authelia in front of selected apps with domain-based policy
|
||||
- fix browser cert pain for apps like Technitium by terminating the public HTTPS edge before the self-signed backend
|
||||
- avoid giving Traefik Docker socket access; routes are explicit file-provider config
|
||||
|
||||
Design choices:
|
||||
- Traefik is internal-only on the `pangolin` Docker network
|
||||
- no host port publishing
|
||||
- no ACME on PD
|
||||
- no Docker provider / no docker.sock mount
|
||||
- Pangolin resources should target `traefik:80` on site 4 when an app is cut over to this layer
|
||||
- Authelia remains the identity decision point for domain/group access
|
||||
|
||||
Current routed hostnames in dynamic config:
|
||||
- `auth.paccoco.com` -> Authelia
|
||||
- `gitea.paccoco.com` -> Gitea (Authelia-protected)
|
||||
- `grafana.paccoco.com` -> Grafana (Authelia-protected)
|
||||
- `dns.paccoco.com` -> Technitium (Authelia-protected)
|
||||
- `traefik.paccoco.com` -> Traefik dashboard (Authelia-protected)
|
||||
|
||||
Cutover note:
|
||||
- Deploying this stack does not automatically rewrite Pangolin resources.
|
||||
- The secure end state is: Pangolin tunnel -> Traefik -> app.
|
||||
- If an existing Pangolin resource still points directly at an app, that app will keep behaving the old way until its target is changed.
|
||||
32
ingress/docker-compose.yaml
Normal file
32
ingress/docker-compose.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
name: ingress
|
||||
|
||||
networks:
|
||||
pangolin:
|
||||
external: true
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.1
|
||||
container_name: traefik
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_BIND_SERVICE
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp
|
||||
- /run
|
||||
networks:
|
||||
- pangolin
|
||||
volumes:
|
||||
- /mnt/docker-ssd/docker/compose/ingress/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
|
||||
- /mnt/docker-ssd/docker/compose/ingress/traefik/dynamic:/etc/traefik/dynamic:ro
|
||||
healthcheck:
|
||||
test: ["CMD", "traefik", "healthcheck", "--ping"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
89
ingress/traefik/dynamic/routes.yml
Normal file
89
ingress/traefik/dynamic/routes.yml
Normal file
@@ -0,0 +1,89 @@
|
||||
http:
|
||||
routers:
|
||||
auth:
|
||||
rule: Host(`auth.paccoco.com`)
|
||||
entryPoints: [web]
|
||||
service: authelia
|
||||
middlewares:
|
||||
- security-headers
|
||||
|
||||
gitea:
|
||||
rule: Host(`gitea.paccoco.com`)
|
||||
entryPoints: [web]
|
||||
service: gitea
|
||||
middlewares:
|
||||
- security-headers
|
||||
- authelia-forwardauth
|
||||
|
||||
grafana:
|
||||
rule: Host(`grafana.paccoco.com`)
|
||||
entryPoints: [web]
|
||||
service: grafana
|
||||
middlewares:
|
||||
- security-headers
|
||||
- authelia-forwardauth
|
||||
|
||||
technitium:
|
||||
rule: Host(`dns.paccoco.com`)
|
||||
entryPoints: [web]
|
||||
service: technitium
|
||||
middlewares:
|
||||
- security-headers
|
||||
- authelia-forwardauth
|
||||
|
||||
traefik-dashboard:
|
||||
rule: Host(`traefik.paccoco.com`)
|
||||
entryPoints: [web]
|
||||
service: api@internal
|
||||
middlewares:
|
||||
- security-headers
|
||||
- authelia-forwardauth
|
||||
|
||||
services:
|
||||
authelia:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://authelia:9091
|
||||
|
||||
gitea:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://gitea:3000
|
||||
|
||||
grafana:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: http://grafana:3000
|
||||
|
||||
technitium:
|
||||
loadBalancer:
|
||||
passHostHeader: true
|
||||
serversTransport: technitium-selfsigned
|
||||
servers:
|
||||
- url: https://technitium-dns-pilot:443
|
||||
|
||||
middlewares:
|
||||
authelia-forwardauth:
|
||||
forwardAuth:
|
||||
address: http://authelia:9091/api/authz/forward-auth
|
||||
trustForwardHeader: true
|
||||
authResponseHeaders:
|
||||
- Remote-User
|
||||
- Remote-Groups
|
||||
- Remote-Name
|
||||
- Remote-Email
|
||||
|
||||
security-headers:
|
||||
headers:
|
||||
frameDeny: true
|
||||
browserXssFilter: true
|
||||
contentTypeNosniff: true
|
||||
referrerPolicy: same-origin
|
||||
customRequestHeaders:
|
||||
X-Forwarded-Proto: https
|
||||
customResponseHeaders:
|
||||
X-Robots-Tag: noindex, nofollow, noarchive, nosnippet
|
||||
|
||||
serversTransports:
|
||||
technitium-selfsigned:
|
||||
insecureSkipVerify: true
|
||||
22
ingress/traefik/traefik.yml
Normal file
22
ingress/traefik/traefik.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
global:
|
||||
checkNewVersion: false
|
||||
sendAnonymousUsage: false
|
||||
|
||||
api:
|
||||
dashboard: true
|
||||
|
||||
ping: {}
|
||||
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
|
||||
providers:
|
||||
file:
|
||||
directory: /etc/traefik/dynamic
|
||||
watch: true
|
||||
|
||||
log:
|
||||
level: INFO
|
||||
|
||||
accessLog: {}
|
||||
Reference in New Issue
Block a user