Skip to content

Instantly share code, notes, and snippets.

@darkxanter
Created February 8, 2022 10:34
Show Gist options
  • Save darkxanter/ed9e9e0d546ae38f1a160c065d1b80cd to your computer and use it in GitHub Desktop.
Save darkxanter/ed9e9e0d546ae38f1a160c065d1b80cd to your computer and use it in GitHub Desktop.
traefik deploy
# this traefik reverse proxy has a bunch of features:
# - reverse proxy all 80/443 ingress traffic on a swarm
# - dynamic config via each app's swarm service labels
# - HA multi-container design for traefik
# - runs traefik on host NIC directly, to improve performance
# and capture client IP's
# - uses consul to store static config for startup
# - uses haproxy to allow offloading traefik to worker nodes
# - store consul data in a volume on cloud storage with rexray
# TODO improvements
# make consul HA
# properly handle service restarts if init container config changes
# use envvars for email and default domain settings
version: '3.7'
x-default-opts:
&default-opts
logging:
options:
max-size: "1m"
# driver: "gelf"
# options:
# gelf-address: "udp://127.0.0.1:5000"
services:
# traefik-init adds the command: config to consul, and then quits
traefik-init:
<<: *default-opts
image: traefik:1.7-alpine
networks:
- traefik-consul
command:
# Use your favourite settings here, but add:
- storeconfig
- --api
# NOTE: you'll want to lower this logLevel for real world stuff
- --logLevel="DEBUG"
# NOTE: you'll want to disable this for anything of signifant traffic, or route logs outside stdout
- --accessLog
- --docker
- --docker.endPoint=http://dockersocket:2375
- --docker.swarmMode
- --docker.domain=traefik
- --docker.network=proxy
- --docker.watch
- --consul
- --consul.endpoint=consul:8500
- --consul.prefix=traefik
- --defaultentrypoints=http,https
- --entryPoints=Name:https Address::443 TLS
- --entryPoints=Name:http Address::80 # don't force HTTPS
# - --entryPoints=Name:http Address::80 Redirect.EntryPoint:https # force HTTPS
## optional LetsEncrypt settings
# - --acme
# - --acme.email=${TRAEFIK_ACME_EMAIL}
# # TODO: envvar for email and default domain
# - --acme.httpchallenge
# - --acme.httpchallenge.entrypoint=http
# - --acme.onhostrule=true
# - --acme.entrypoint=https
# - --acme.storage=my/key
# - --acme.acmelogging
# - --acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
# - --acme.caserver=https://acme-v02.api.letsencrypt.org/directory
deploy:
restart_policy:
condition: on-failure
# actual proxy, running on each node, and using direct host ports
traefik:
<<: *default-opts
image: traefik:1.7-alpine
networks:
- proxy
- traefik-consul
- traefik-docker
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
- target: 8080
published: 8080
protocol: tcp
mode: ingress # traefik dashboard
command:
- --consul
- --consul.endpoint=consul:8500
- --consul.prefix=traefik
deploy:
mode: global
labels:
- traefik.port=8080
- traefik.frontend.rule=Host:traefik.dogvs.cat
# if you have enough servers, make this only run on workers, maybe in a public DMZ
# placement:
# constraints: [node.role == worker]
# stores the proxy config
consul:
<<: *default-opts
image: consul
command: agent -server -bootstrap-expect=1
networks:
- traefik-consul
volumes:
- consul:/consul/data
environment:
- CONSUL_LOCAL_CONFIG={"server":true}
- CONSUL_BIND_INTERFACE=eth0
- CONSUL_CLIENT_INTERFACE=eth0
# this custom haproxy allows us to move traefik to worker nodes
# while this container listens on managers and only allows
# traefik to connect, read-only, to limited docker api calls
# https://github.com/Tecnativa/docker-socket-proxy
dockersocket:
<<: *default-opts
image: tecnativa/docker-socket-proxy
networks:
- traefik-docker
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
# CONTAINERS: 1
NETWORKS: 1
SERVICES: 1
# SWARM: 1
TASKS: 1
deploy:
mode: global
placement:
constraints: [node.role == manager]
volumes:
consul:
driver: ${DOCKER_VOL_DRIVER:-local}
# for example export DOCKER_VOL_DRIVER="rexray/dobs"
driver_opts:
size: 1
networks:
proxy:
driver: overlay
name: proxy
traefik-consul:
driver: overlay
driver_opts:
encrypted: 'true'
# since we're passing SSL certs over TCP, lets IPSec
traefik-docker:
driver: overlay
driver_opts:
encrypted: 'true'
# since we're passing docker socket stuff over TCP, lets IPSec
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment