summaryrefslogtreecommitdiff
path: root/playbooks/roles/traefik/templates/stacks/docker-compose.yml
blob: 46f5503a3d27c4185eb7c433096ac9e725f03065 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
services:
  headscale-client:
    image: tailscale/tailscale:latest
    hostname: headscale-client-{{ deployment_time }}
    environment:
      - DEPLOYMENT_TIME={{ deployment_time }}
      - TZ={{ timezone }}
      - TS_AUTHKEY={{ headscale_user_auth_key }}
      - TS_EXTRA_ARGS=--login-server=https://{{ headscale_host }} --accept-dns --stateful-filtering=false --advertise-routes={{ loadbalancer_ip }}/32
      - TS_STATE_DIR=/var/lib/tailscale
      - TS_USERSPACE=false
    healthcheck:
      test: ["CMD-SHELL", "tailscale status"]
      interval: 1s
      timeout: 5s
      retries: 10
    volumes:
      - "{{ traefik_base }}/volumes/headscale:/var/lib/tailscale"
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN
    networks:
      - headnet
    deploy:
      mode: replicated
      replicas: 1
      update_config:
        parallelism: 1
        order: start-first
        failure_action: rollback
        monitor: 2s
  traefik:
    image: traefik:v3
    depends_on:
      - headscale-client
    ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host # to get x-forwarded-for correctly, see https://github.com/moby/moby/issues/25526
    healthcheck:
      test: traefik healthcheck --ping
      interval: 10s
      retries: 2
      timeout: 3s
    environment:
      - DEPLOYMENT_TIME={{ deployment_time }}
      - TZ={{ timezone }}
      - CF_API_EMAIL={{ cloudflare_email }}
      - CF_DNS_API_TOKEN={{ cloudflare_dns_api_token }}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - "{{ traefik_base }}/stacks/traefik.yml:/traefik.yml"
      - "{{ traefik_base }}/volumes/certs:/certs"
    networks:
      - metrics
      - proxy
      - oauth_proxy
      - headnet
    deploy:
      mode: global
      update_config:
        parallelism: 1
        order: stop-first # only one service eating 80/443 per host, since
        failure_action: rollback
        monitor: 2s # go go go.
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.dashboard.rule=Host(`{{ traefik_domain }}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
        - "traefik.http.routers.dashboard.service=api@internal"
        - "traefik.http.routers.dashboard.tls=true"
        - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
        - "traefik.http.services.dashboard.loadbalancer.server.port=8080"
        - "traefik.http.routers.ping.rule=Host(`{{ traefik_domain }}`) && PathPrefix(`/ping`)"
        - "traefik.http.routers.ping.service=ping@internal"
        - "traefik.http.routers.ping.tls=true"
        - "traefik.http.routers.ping.tls.certresolver=letsencrypt"
        - "traefik.http.services.ping.loadbalancer.server.port=8080"

        - "traefik.http.middlewares.auth-headers.headers.stsSeconds=315360000"
        - "traefik.http.middlewares.auth-headers.headers.browserXssFilter=true"
        - "traefik.http.middlewares.auth-headers.headers.contentTypeNosniff=true"
        - "traefik.http.middlewares.auth-headers.headers.forceSTSHeader=true"
        - "traefik.http.middlewares.auth-headers.headers.stsIncludeSubdomains=true"
        - "traefik.http.middlewares.auth-headers.headers.stsPreload=true"
        - "traefik.http.middlewares.auth-headers.headers.frameDeny=true"

        - "traefik.http.middlewares.oauth-verify.forwardAuth.address=http://oauth2-proxy:4180"
        - "traefik.http.middlewares.oauth-verify.forwardAuth.trustForwardHeader=true"
        - "traefik.http.middlewares.oauth-verify.forwardAuth.authResponseHeaders={{ forwardauth_headers }}"

        - "traefik.http.middlewares.oauth-verify-noredirect.forwardAuth.address=http://oauth2-proxy:4180/oauth2/auth"
        - "traefik.http.middlewares.oauth-verify-noredirect.forwardAuth.trustForwardHeader=true"
        - "traefik.http.middlewares.oauth-verify-noredirect.forwardAuth.authResponseHeaders={{ forwardauth_headers }}"

  oauth2-proxy:
    image: quay.io/oauth2-proxy/oauth2-proxy:latest
    command: --alpha-config /conf/oauth_proxy_alpha.yml --config /conf/oauth_proxy.cfg
    volumes:
      - "{{ traefik_base }}/volumes/oauth2proxy:/conf"
    environment:
      - TZ={{ timezone }}
      - DEPLOYMENT_TIME={{ deployment_time }}
    networks:
      - oauth_cache
      - proxy
      - oauth_proxy
      - metrics
    deploy:
      mode: replicated
      update_config:
        parallelism: 1
        failure_action: rollback
        order: start-first
        delay: 5s
      replicas: 1
      labels:
        "traefik.enable": "true"
        "traefik.swarm.network": "proxy"
        "traefik.http.routers.fwdauth.tls": "true"
        "traefik.http.routers.fwdauth.tls.certResolver": "letsencrypt"
        "traefik.http.routers.fwdauth.rule": "!Host(`{{ idm_domain }}`) && (PathPrefix(`/oauth2`) || Host(`{{ oauth_proxy_domain }}`))"
        "traefik.http.routers.fwdauth.entrypoints": "websecure"
        "traefik.http.routers.fwdauth.middlewares": "auth-headers"
        "traefik.http.services.fwdauth.loadbalancer.server.port": "4180"
  oauth2-cache:
    image: redis:8-alpine
    restart: always
    command: redis-server --save 20 1 --loglevel warning
    volumes:
      - "{{ traefik_base }}/volumes/redis:/data"
    environment:
      - TZ={{ timezone }}
      - DEPLOYMENT_TIME={{ deployment_time }}
    networks:
      - oauth_cache
    deploy:
      mode: replicated
      update_config:
        parallelism: 1
        failure_action: rollback
        order: start-first
        delay: 5s
      replicas: 1

networks:
  metrics:
    external: true
  proxy:
    name: proxy
    driver: overlay
    attachable: true
  oauth_proxy:
  oauth_cache:
  headnet: