diff --git a/docker-traefik-tcp/README.md b/docker-traefik-tcp/README.md new file mode 100644 index 0000000..39ece7d --- /dev/null +++ b/docker-traefik-tcp/README.md @@ -0,0 +1,30 @@ +# docker-traefik-tcp + +Simple `docker-compose.yml` template to run Traefik in Docker with TCP routers. + +Port 443 is TCP-router enabled, it will use LetsEncrypt to create a cert for `HostSNI()`, you can connect to it via TLS, for example using `openssl s_client -connect tcp.example.com:443`. With this multiple (sub-)domains can be used, Traefik managing TLS and forwarding data stream un-encrypted. + +Port 9000 is TCP-router enabled, just for plain TCP. Traefik can not see anything inside that connection, so only HostSNI(`*`) can be used for a single service. If you enable any TLS on the router, then Traefik will create a default cert, unless you load a custom TLS cert via `provider.file`. The target service can use plain TCP or create it's own custom TLS cert. Note that LetsEncrypt with httpChallenge and tlsChallenge only works with ports 80/443, so if the service wants to create a LE cert, it needs to use dnsChallenge. + +## Features: + +- Traefik is listening on ports 80 (http), 443 (https) and 9000 (plain TCP) +- All http requests will be redirected to secure https requests +- Docker services with label `traefik.enable=true` will automatically be discovered by Traefik +- Letsencrypt will automatically generate TLS/SSL certificates for all domains in `Host()` and `HostSNI()` +- Traefik log (`level=INFO`) and access log are enabled to container stdout/stderr +- Traefik dashboard is enabled at `https://traefik.example.com/dashboard/` with user/pass test/test +- Example whoami router will automatically redirect from "www.whoami.example.com" to "whoami.example.com" + +## Deployment: + +- Adapt all domain names in `Host()` and `HostSNI()` +- Adapt `acme.email` +- Adapt dashboard username/password +- For production: write logs files to mounted folder on host +- Run `docker compose up -d` + +## Notes: + +- `websecure` entrypoint has LetsEncrypt for http(s), but the TCP router needs an additional LE assignment + diff --git a/docker-traefik-tcp/docker-compose.yml b/docker-traefik-tcp/docker-compose.yml new file mode 100644 index 0000000..381fed5 --- /dev/null +++ b/docker-traefik-tcp/docker-compose.yml @@ -0,0 +1,89 @@ +version: '3.9' + +networks: + proxy: + name: proxy + #external: true + +volumes: + letsencrypt: + name: letsencrypt + +services: + traefik: + image: traefik:v2.10 + ports: + - target: 80 + published: 80 + protocol: tcp + mode: host + - target: 443 + published: 443 + protocol: tcp + mode: host + - target: 9000 + published: 9000 + protocol: tcp + mode: host + networks: + - proxy + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - letsencrypt:/letsencrypt + #- /var/log:/var/log + command: + - --api.dashboard=true + - --log.level=INFO + #- --log.filepath=/var/log/traefik.log + - --accesslog=true + #- --accesslog.filepath=/var/log/traefik-access.log + - --providers.docker=true + - --providers.docker.exposedByDefault=false + - --entryPoints.web.address=:80 + - --entryPoints.web.http.redirections.entryPoint.to=websecure + - --entryPoints.web.http.redirections.entryPoint.scheme=https + - --entryPoints.websecure.address=:443 + - --entrypoints.websecure.http.tls.certresolver=myresolver + - --entryPoints.tcp-plain.address=:9000 + - --certificatesresolvers.myresolver.acme.tlschallenge=true + - --certificatesResolvers.myresolver.acme.email=email@example.com + - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json + labels: + - traefik.enable=true + - traefik.http.routers.mydashboard.entrypoints=websecure + - traefik.http.routers.mydashboard.rule=Host(`traefik.example.com`) + - traefik.http.routers.mydashboard.service=api@internal + - traefik.http.routers.mydashboard.middlewares=myauth + - traefik.http.middlewares.myauth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/ + + whoami: + image: traefik/whoami:v1.9 + networks: + - proxy + labels: + - traefik.enable=true + - traefik.http.routers.whoami.entrypoints=websecure + - traefik.http.routers.whoami.rule=Host(`whoami.example.com`) + - traefik.http.services.whoami.loadbalancer.server.port=80 + + tcpecho-le: + image: istio/tcp-echo-server:1.2 + networks: + - proxy + labels: + - traefik.enable=true + - traefik.tcp.routers.tcpecho-le.entrypoints=websecure + - traefik.tcp.routers.tcpecho-le.rule=HostSNI(`tcp.example.com`) + - traefik.tcp.routers.tcpecho-le.tls.certresolver=myresolver + - traefik.tcp.services.tcpecho-le.loadbalancer.server.port=9000 + + tcpecho-plain: + image: istio/tcp-echo-server:1.2 + networks: + - proxy + labels: + - traefik.enable=true + - traefik.tcp.routers.tcpecho-plain.entrypoints=tcp-plain + - traefik.tcp.routers.tcpecho-plain.rule=HostSNI(`*`) + - traefik.tcp.services.tcpecho-plain.loadbalancer.server.port=9000 +