migrate infra from single server to multi-server cluster

This commit is contained in:
Marcel Arndt
2025-12-12 11:41:32 +01:00
parent b1a70673a4
commit 156733f65a
63 changed files with 2219 additions and 3 deletions
@@ -0,0 +1,18 @@
[http]
[http.middlewares]
[http.middlewares.authentik.forwardAuth]
address = "http://authentik_server:9000/outpost.goauthentik.io/auth/traefik"
trustForwardHeader = true
authResponseHeaders = [
"X-authentik-username",
"X-authentik-groups",
"X-authentik-email",
"X-authentik-name",
"X-authentik-uid",
"X-authentik-jwt",
"X-authentik-meta-jwks",
"X-authentik-meta-outpost",
"X-authentik-meta-provider",
"X-authentik-meta-app",
"X-authentik-meta-version"
]
@@ -0,0 +1,80 @@
[global]
checkNewVersion = true
sendAnonymousUsage = false
[experimental]
otlpLogs = true
[core]
defaultRuleSyntax = "v2"
[accessLog]
filePath = "/logs/access.log"
format = "json"
# Enable the Dashboard
[api]
dashboard = true
# Write out Traefik logs
[log]
level = "INFO"
format = "json"
filePath = "/logs/traefik.log"
# [log.otlp.http]
# endpoint = "http://signoz_otel-collector:4318/v1/logs"
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.http.redirections.entryPoint]
to = "https"
scheme = "https"
[entryPoints.https]
address = ":443"
# [entryPoints.https.http.tls]
# certResolver = "main"
# OTel
# [tracing]
# serviceName = "traefik"
# [tracing.otlp.http]
# endpoint = "http://signoz_otel-collector:4318/v1/traces"
# [tracing.otlp.http.tls]
# insecureSkipVerify = true
# # Metrics
# [metrics]
# addInternals = false
# [metrics.otlp]
# serviceName = "traefik"
# addEntryPointsLabels = true
# addRoutersLabels = true
# addServicesLabels = true
# [metrics.otlp.http]
# endpoint = "http://signoz_otel-collector:4318/v1/metrics"
# [metrics.otlp.grpc]
# endpoint = "monitoring_alloy:4317"
# insecure = true
# Let's Encrypt
[certificatesResolvers.main.acme]
email = "ma@coachhamburg.com"
storage = "acme.json"
# uncomment to use staging CA for testing
# caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
# [certificatesResolvers.main.acme.tlsChallenge]
[certificatesResolvers.main.acme.dnsChallenge]
provider = "hetzner"
# Uncomment to use HTTP validation, like a caveman!
# [certificatesResolvers.main.acme.httpChallenge]
# entryPoint = "http"
[providers]
[providers.swarm]
endpoint = "unix:///var/run/docker.sock"
exposedByDefault = false
[providers.file]
directory = "/etc/traefik/dynamic"
watch = true
@@ -0,0 +1,44 @@
---
- name: TRAEFIK | Copy Stack Files
copy:
directory_mode: true
src: traefik
dest: "{{ ceph_volume }}"
run_once: true
delegate_to: "{{ groups['managers'][0] }}"
- name: TRAEFIK | Generate Compose file
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ data_dir }}/traefik.yml"
mode: 0644
run_once: true
delegate_to: "{{ groups['managers'][0] }}"
- name: TRAEFIK | Ensure permissions on acme.json
ansible.builtin.file:
path: "{{ data_dir }}/data/acme.json"
mode: '0600'
run_once: true
delegate_to: "{{ groups['managers'][0] }}"
- name: TRAEFIK | traefik_public Netzwerk erstellen
community.docker.docker_network:
name: traefik_public
driver: overlay
state: present
attachable: yes
ipam_config:
- subnet: '172.16.200.0/24'
gateway: '172.16.200.1'
run_once: true
delegate_to: "{{ groups['managers'][0] }}"
- name: TRAEFIK | Deploy app stack
community.docker.docker_stack:
state: present
name: traefik
compose:
- "{{ data_dir }}/traefik.yml"
delegate_to: "{{ groups['managers'][0] }}"
run_once: true
@@ -0,0 +1,52 @@
services:
app:
image: traefik:v3.6.2
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
- target: 8080
published: 8080
protocol: tcp
environment:
- HETZNER_API_TOKEN={{ hetzner_api_key }}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- {{ data_dir }}/config:/etc/traefik
- {{ data_dir }}/data/logs:/logs
- {{ data_dir }}/data/acme.json:/acme.json
# healthcheck:
# test: ["CMD", "traefik", "healthcheck", "--ping"]
# timeout: 1s
# interval: 10s
# retries: 3
# start_period: 10s
networks:
- {{ traefik_public_net }}
# Global mode makes an instance of traefik listen on _every_ node, so that regardless of which
# node the request arrives on, it'll be forwarded to the correct backend service.
deploy:
mode: global
labels:
- "traefik.enable=true"
- "traefik.swarm.network={{ traefik_public_net }}"
- "traefik.http.routers.api.rule=Host(`{{ subdomain }}.{{ main_domain }}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
- "traefik.http.routers.api.entrypoints=https"
{% if use_authentik %} - "traefik.http.routers.api.middlewares=authentik@file"{% endif %}
# - "traefik.http.routers.api.tls.domains[0].main={{ main_domain }}"
# - "traefik.http.routers.api.tls.domains[0].sans=*.{{ main_domain }}"
- "traefik.http.routers.api.tls=true"
- "traefik.http.routers.api.tls.certresolver=main"
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.services.dummy.loadbalancer.server.port=9999"
placement:
constraints: [node.role == manager]
networks:
{{ traefik_public_net }}:
external: true
@@ -0,0 +1,3 @@
subdomain: router
use_authentik: false
data_dir: "{{ ceph_volume }}/traefik"