Using traefik 3 I want to route wg.my-domain.com
to wg-easy UI which is listening on port 51821
of the wg-easy service. But I want to only allow so on the private network 10.0.0.0/24
.
For now I point wg.my-domain.com
to 10.0.0.4
in my /etc/hosts
. I do control my-domain.com
and the cert is created and valid. There is no A
record for wg.my-domain.com
.
When I map the port on the private ip using docker ports
(see comment in the config), I can access the ui on http://10.0.0.4:51821
but I want to only allow access via the domain and use ssl (https://wg.my-domain.com
).
My problem is, that when I go to https://wg.my-domain.com
I only see 404 page not found
. I expected it to work after I set traefik.http.routers.wg_easy.loadbalancer.server.port=51821
to tell the traefik router to route the domain to that specific port of the container.
Here is my docker-compose.yml:
services:
traefik:
image: traefik:3.0
command:
# - "--log.level=DEBUG"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--api.dashboard=false"
- "--entryPoints.web.forwardedHeaders.trustedIPs=127.0.0.1/32"
# use DNS challenge because we issue certs for services not having A records in public DNS
- "--certificatesresolvers.leresolver.acme.dnschallenge=true"
- "--certificatesresolvers.leresolver.acme.dnschallenge.provider=hetzner"
- "--certificatesresolvers.leresolver.acme.storage=/letsencrypt/acme.json"
environment:
- "HETZNER_API_KEY=${HETZNER_DNS_API_KEY}"
ports:
- ${PRIVATE_IPV4}:80:80 # traefik
- 443:443
volumes:
- ./traefik/certs:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
wg-easy:
image: ghcr.io/wg-easy/wg-easy:13
environment:
# ⚠️ Required:
- WG_HOST=<my-public-ip>
# Optional:
# - WEBUI_HOST=10.0.0.4
- PORT=51821 # web ui port
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
volumes:
- ./wg-easy:/etc/wireguard
ports:
- "51820:51820/udp"
# I don't want to expose the UI port, but only allow accessing it via the domain via traefik on 10.0.0.0/24
# When mapping the port on the private ip, I can access the ui on http://<ip>:51821 but I want to only allow access via the domain and use ssl.
# - "${PRIVATE_IPV4}:51821:51821/tcp"
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.wg_easy.rule=Host(`wg.my-domain.com`)"
- "traefik.http.routers.wg_easy.entrypoints=websecure"
- "traefik.http.routers.wg_easy.loadbalancer.server.port=51821"
- "traefik.http.routers.wg_easy.tls=true"
- "traefik.http.routers.wg_easy.tls.certresolver=leresolver"
The loadbalancer is part of the service and not of routing, so the port must be set like this:
-traefik.http.routers.wg_easy.loadbalancer.server.port=51821
+traefik.http.services.wg_easy.loadbalancer.server.port=51821