138 lines
3.9 KiB
YAML
138 lines
3.9 KiB
YAML
version: '3.8'
|
|
|
|
networks:
|
|
traefik-public:
|
|
external: true
|
|
|
|
volumes:
|
|
traefik_letsencrypt:
|
|
external: true
|
|
|
|
|
|
configs:
|
|
traefik_dynamic:
|
|
external: true
|
|
|
|
|
|
secrets:
|
|
cf_api_token:
|
|
external: true
|
|
|
|
|
|
services:
|
|
traefik:
|
|
image: traefik:latest
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
- "8080:8080"
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- traefik_letsencrypt:/letsencrypt
|
|
networks:
|
|
- traefik-public
|
|
secrets:
|
|
- cf_api_token
|
|
environment:
|
|
# Cloudflare API Token (with DNS edit permissions for your domain)
|
|
- CF_DNS_API_TOKEN_FILE=/run/secrets/cf_api_token
|
|
- CF_ZONE_API_TOKEN_FILE=/run/secrets/cf_api_token
|
|
|
|
# Optional: your Pi-hole DNS can stay
|
|
dns:
|
|
- 192.168.1.196
|
|
- 192.168.1.245
|
|
- 1.1.1.1
|
|
|
|
command:
|
|
# Entrypoints
|
|
- "--entrypoints.web.address=:80"
|
|
- "--entrypoints.websecure.address=:443"
|
|
|
|
# SWARM Provider
|
|
- "--providers.swarm=true"
|
|
- "--providers.swarm.network=traefik-public"
|
|
- "--providers.swarm.exposedbydefault=false"
|
|
|
|
# File Provider (Dynamic Config)
|
|
- "--providers.file.filename=/dynamic.yml"
|
|
- "--providers.file.watch=true"
|
|
|
|
# Dashboard
|
|
- "--api.dashboard=true"
|
|
- "--api.insecure=false"
|
|
|
|
# HTTP -> HTTPS
|
|
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
|
|
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
|
|
|
|
# Let's Encrypt / ACME Cloudflare DNS Challenge
|
|
- "--certificatesresolvers.cfresolver.acme.email=sterlenjohnson6@gmail.com"
|
|
- "--certificatesresolvers.cfresolver.acme.storage=/letsencrypt/acme.json"
|
|
- "--certificatesresolvers.cfresolver.acme.dnschallenge=true"
|
|
- "--certificatesresolvers.cfresolver.acme.dnschallenge.provider=cloudflare"
|
|
|
|
# Optional: increase delay for propagation
|
|
- "--certificatesresolvers.cfresolver.acme.dnschallenge.propagation.delayBeforeChecks=60"
|
|
# Logging
|
|
- "--log.level=INFO"
|
|
|
|
deploy:
|
|
placement:
|
|
constraints:
|
|
- node.role == manager
|
|
labels:
|
|
# Dashboard Router
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.traefik.rule=Host(`traefik.sterl.xyz`)"
|
|
- "traefik.http.routers.traefik.entrypoints=websecure"
|
|
- "traefik.http.routers.traefik.tls.certresolver=cfresolver"
|
|
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
|
|
- "traefik.http.routers.traefik.service=api@internal"
|
|
|
|
whoami:
|
|
image: traefik/whoami
|
|
networks:
|
|
- traefik-public
|
|
deploy:
|
|
labels:
|
|
# Whoami Router
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.whoami.rule=Host(`whoami.sterl.xyz`)"
|
|
- "traefik.http.routers.whoami.entrypoints=websecure"
|
|
- "traefik.http.routers.whoami.tls.certresolver=cfresolver"
|
|
- "traefik.http.services.whoami.loadbalancer.server.port=80"
|
|
|
|
docktail:
|
|
image: ghcr.io/marvinvr/docktail:latest
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
networks:
|
|
- traefik-public
|
|
environment:
|
|
# Optional: Your Tailscale Auth Key if not using tag approval flow
|
|
- TAILSCALE_AUTH_KEY=tskey-auth-ksGqv9DLDZ11CNTRL-TPrRcTiHWYUyuVskzy4nYUGwm2bxPM2d
|
|
# Optional: Set log level
|
|
# - DOCKTAIL_LOG_LEVEL=info
|
|
# Optional: Specify a Tailnet IP for the container itself if needed
|
|
# - DOCKTAIL_TAILNET_IP=100.x.y.z
|
|
deploy:
|
|
mode: global # Run DockTail on all Swarm nodes
|
|
resources:
|
|
limits:
|
|
memory: 128M
|
|
cpus: '0.2'
|
|
reservations:
|
|
memory: 32M
|
|
cpus: '0.05'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 5s
|
|
max_attempts: 3
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 15s
|
|
|