|
version: '3.6' |
|
|
|
networks: |
|
docker-proxy-internal: |
|
internal: |
|
external: |
|
name: traefik-proxy |
|
|
|
volumes: |
|
# Volumes for traefik certificates and logs |
|
traefik-letsencrypt: |
|
traefik-logs: |
|
|
|
services: |
|
# proxy to avoid direct connection to the docker socket. |
|
proxy: |
|
image: tecnativa/docker-socket-proxy |
|
volumes: |
|
- /var/run/docker.sock:/var/run/docker.sock:ro |
|
environment: |
|
- CONTAINERS=1 |
|
privileged: true |
|
networks: |
|
- docker-proxy-internal |
|
## Traefik concepts |
|
# Providers : discover the services that live on your infrastructure (their IP, health, ...) |
|
# Entrypoints : listen for incoming traffic (ports, ...) |
|
# Routers : analyse the requests (host, path, headers, SSL, ...). A router is in charge of connecting incoming requests to the services that can handle them. |
|
# Services : forward the request to your services (load balancing, ...). The Services are responsible for configuring how to reach the actual services that will eventually handle the incoming requests. |
|
# Middlewares : may update the request or make decisions based on the request (authentication, rate limiting, headers, ...) |
|
|
|
## Traefik : routing services from declared labels |
|
# dashboard : https://traefik.HOST/ |
|
# prometheus : https://traefik-metrics.HOST/metrics |
|
traefik: |
|
image: traefik:latest |
|
container_name: "traefik" |
|
command: |
|
- --log.level=DEBUG |
|
- --api.dashboard=true |
|
- --api.insecure=true |
|
# Do not expose all Docker services by default |
|
- --providers.docker=true |
|
- --providers.docker.exposedbydefault=false |
|
#- "--providers.docker.endpoint=unix:///var/run/docker.sock" |
|
- --providers.docker.endpoint=tcp://proxy:2375 |
|
- --providers.docker.network=traefik-proxy |
|
|
|
# DNS Challenge (domain.tld and *.domain.tld DNS zones are defined there) : hetzner |
|
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" |
|
- --certificatesresolvers.myresolver.acme.email=postmaster@${SERVER_HOSTNAME} |
|
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json |
|
- --certificatesresolvers.myresolver.acme.dnschallenge=true |
|
- --certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0 |
|
- --certificatesresolvers.myresolver.acme.dnschallenge.provider=hetzner |
|
- --certificatesresolvers.myresolver.acme.dnschallenge.resolvers=helium.ns.hetzner.de,hydrogen.ns.hetzner.com,oxygen.ns.hetzner.com |
|
|
|
# HTTPS : port 443, with letsencrypt certificates provided by myresolver |
|
- --entrypoints.websecure.address=:443 |
|
- --entrypoints.websecure.http.tls=true |
|
- --entrypoints.websecure.http.tls.certResolver=myresolver |
|
#- --entrypoints.websecure.http.tls.domains[0].main=${SERVER_HOSTNAME} |
|
#- --entrypoints.websecure.http.tls.domains[0].sans=*.${SERVER_HOSTNAME} |
|
- --entrypoints.websecure.http.tls.domains[0].main=${CERT_DOMAIN} |
|
- --entrypoints.websecure.http.tls.domains[0].sans=*.${CERT_DOMAIN} |
|
- --entrypoints.websecure.http.tls.domains[0].main=${SERVER_HOSTNAME} |
|
- --entrypoints.websecure.http.tls.domains[1].sans=*.${SERVER_HOSTNAME} |
|
# staging letsencrypt (no quotas, but self signed certificates), comment to move to prod |
|
#- --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory |
|
#- "--providers.docker.defaultRule=Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" |
|
|
|
# Redirect HTTP (web) to HTTPS (websecure) |
|
- --entrypoints.web.address=:80 |
|
- --entrypoints.web.http.redirections.entryPoint.to=websecure |
|
- --entrypoints.web.http.redirections.entryPoint.scheme=https |
|
- --entrypoints.web.http.redirections.entrypoint.permanent=true |
|
|
|
# Expose prometheus metrics on port 8082 (rerouted by labels) |
|
- --metrics.prometheus=true |
|
- '--metrics.prometheus.buckets=0.1,0.3,1.2,5.0' |
|
- --metrics.prometheus.addrouterslabels=true |
|
- --metrics.prometheus.addServicesLabels=true |
|
- --metrics.prometheus.addEntryPointsLabels=true |
|
- --entryPoints.metrics.address=:8082 |
|
- --metrics.prometheus.entryPoint=metrics |
|
- --metrics.prometheus.manualrouting=true |
|
- --accesslog=true |
|
|
|
- --entryPoints.mainnet-mezos-lb.address=:39090 |
|
#- --entryPoints.mainnet-mezos-lb.proxyProtocol.insecure |
|
- --entryPoints.mainnet-mezos-lb.proxyProtocol.trustedIPs=${trustedIPs} |
|
- --entryPoints.mainnet-mezos-lb.http.tls=false |
|
|
|
- --entryPoints.mainnet-graphic-proxy-lb.address=:49090 |
|
#- --entryPoints.mainnet-graphic-proxy.proxyProtocol.insecure |
|
- --entryPoints.mainnet-graphic-proxy-lb.proxyProtocol.trustedIPs=${trustedIPs} |
|
- --entryPoints.mainnet-graphic-proxy-lb.http.tls=false |
|
|
|
# Writing Logs to a File |
|
# - "--log.filePath=/logs/traefik.log" |
|
# Writing Logs to a File, format = common or json |
|
#- "--log.format=common" |
|
# Acepted log levels = DEBUG, PANIC, FATAL, ERROR, WARN, and INFO |
|
- "--log.level=DEBUG" |
|
#- "--tracing=true" |
|
- "--pilot.token=${traefik_pilot_token}" |
|
environment: |
|
- HETZNER_API_KEY=${traefik_DNS_cert_Hetzner_API_Key:-notset} |
|
restart: always |
|
ports: |
|
- "80:80" |
|
- "443:443" |
|
- "39090:39090" |
|
- "49090:49090" |
|
#- "8080:8080" default for dashboard, routed to https with labels |
|
#- "8082:8082" set for prometheus, rerouted to http with labels |
|
volumes: |
|
- traefik-letsencrypt:/letsencrypt |
|
- traefik-logs:/logs |
|
- "/var/run/docker.sock:/var/run/docker.sock:ro" |
|
networks: |
|
- internal |
|
- docker-proxy-internal |
|
# deploy: |
|
# placement: |
|
# constraints: |
|
# - node.role == manager |
|
labels: |
|
#"traefik.frontend.rule: HostRegexp(`{catchall:.*}`)" |
|
traefik.enable: true |
|
# prometheus exporter |
|
traefik.http.routers.traefikmetrics.rule: Host(`traefik-metrics.${SERVER_HOSTNAME}`) |
|
traefik.http.routers.traefikmetrics.entrypoints: websecure |
|
traefik.http.routers.traefikmetrics.service: prometheus@internal |
|
traefik.http.services.traefikmetrics.loadbalancer.server.port: 8082 |
|
traefik.http.routers.traefikmetrics.tls.certresolver: myresolver |
|
# traefik dasboard |
|
traefik.http.routers.api.rule: Host(`traefik.${SERVER_HOSTNAME}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`)) |
|
traefik.http.routers.api.entrypoints: websecure |
|
traefik.http.routers.api.service: api@internal |
|
traefik.http.services.api.loadbalancer.server.port: 8080 |
|
traefik.http.routers.api.tls.certresolver: myresolver |
|
traefik.http.middlewares.default-compress.compress: 'true' |
|
traefik.http.middlewares.default-http.redirectScheme.scheme: https |
|
traefik.http.middlewares.default-http.redirectScheme.permanent: 'true' |
|
traefik.http.middlewares.default-https.chain.middlewares: default-compress |
|
|
|
whoami-monitoring: |
|
image: "traefik/whoami" |
|
container_name: "whoami-monitoring" |
|
networks: |
|
- internal |
|
- docker-proxy-internal |
|
labels: |
|
traefik.enable: true |
|
traefik.docker.network: traefik-proxy |
|
traefik.http.routers.whoami-monitoring.rule: Host(`whoami22.${DOMAIN?err}`) |
|
traefik.http.routers.whoami-monitoring.middlewares: oauth-signin,oauth-verify,default-https |
|
traefik.http.routers.whoami-monitoring.entrypoints: websecure |
|
traefik.http.services.whoami-monitoring.loadbalancer.server.port: 80 |
|
|
|
oauth2: |
|
# image: quay.io/pusher/oauth2_proxy:${OAUTH2_PROXY_VERSION} |
|
image: quay.io/oauth2-proxy/oauth2-proxy:${OAUTH2_PROXY_VERSION} |
|
container_name: "oauth" |
|
restart: unless-stopped |
|
healthcheck: |
|
test: ["CMD", "wget", "--tries=1", "--spider", "http://oauth:4180/ping"] |
|
interval: 30s |
|
timeout: 10s |
|
labels: |
|
ai.ix.expose: 'true' |
|
traefik.enable: 'true' |
|
traefik.http.middlewares.oauth-verify.forwardAuth.address: http://oauth:4180/oauth2/auth |
|
traefik.http.middlewares.oauth-verify.forwardAuth.trustForwardHeader: 'true' |
|
traefik.http.middlewares.oauth-verify.forwardAuth.authResponseHeaders: X-Auth-Request-User,X-Auth-Request-Email,Set-Cookie,X-Auth-User,X-Secret |
|
traefik.http.middlewares.oauth-signin.errors.service: oauth@docker |
|
traefik.http.middlewares.oauth-signin.errors.status: '401' |
|
traefik.http.middlewares.oauth-signin.errors.query: /oauth2/sign_in |
|
traefik.http.routers.oauth.entrypoints: websecure |
|
traefik.http.routers.oauth.rule: Host(`oauth.${DOMAIN?err}`) || PathPrefix(`/oauth2`) |
|
traefik.http.routers.oauth.tls.certResolver: myresolver |
|
traefik.http.routers.oauth.service: oauth@docker |
|
traefik.http.services.oauth.loadbalancer.server.port: '4180' |
|
environment: |
|
# https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview/#environment-variables |
|
OAUTH2_PROXY_PROVIDER: gitlab |
|
OAUTH2_PROXY_GITLAB_GROUP: ${OAUTH2_PROXY_GITLAB_GROUP} |
|
OAUTH2_PROXY_CLIENT_ID: ${OAUTH2_PROXY_CLIENT_ID?err} |
|
OAUTH2_PROXY_CLIENT_SECRET: ${OAUTH2_PROXY_CLIENT_SECRET?err} |
|
OAUTH2_PROXY_COOKIE_DOMAINS: ${DOMAIN?err} |
|
OAUTH2_PROXY_COOKIE_REFRESH: '1h' |
|
OAUTH2_PROXY_COOKIE_SECURE: 'false' |
|
OAUTH2_PROXY_COOKIE_SECRET: ${OAUTH2_PROXY_COOKIE_SECRET?err} |
|
OAUTH2_PROXY_EMAIL_DOMAINS: '*' |
|
OAUTH2_PROXY_FOOTER: '-' |
|
OAUTH2_PROXY_HTTP_ADDRESS: '0.0.0.0:4180' |
|
OAUTH2_PROXY_PASS_BASIC_AUTH: 'false' |
|
OAUTH2_PROXY_PASS_USER_HEADERS: 'true' |
|
OAUTH2_PROXY_REVERSE_PROXY: 'true' |
|
OAUTH2_PROXY_SET_AUTHORIZATION_HEADER: 'true' |
|
OAUTH2_PROXY_SET_XAUTHREQUEST: 'true' |
|
OAUTH2_PROXY_WHITELIST_DOMAIN: '.${DOMAIN?err}' |
|
OAUTH2_PROXY_REDIRECT_URL: "https://oauth.${DOMAIN}/oauth2/callback" |
|
networks: |
|
- internal |
|
- docker-proxy-internal |