61 lines
1.9 KiB
YAML
61 lines
1.9 KiB
YAML
# Compose v2 (no "version" key needed)
|
|
x-default: &default
|
|
restart: unless-stopped
|
|
networks:
|
|
- traefik
|
|
logging:
|
|
driver: json-file
|
|
options:
|
|
max-size: 50m
|
|
max-file: "2"
|
|
|
|
services:
|
|
headscale:
|
|
<<: *default
|
|
image: docker.io/headscale/headscale:latest
|
|
container_name: headscale
|
|
command: serve
|
|
# Optional: expose metrics to host only
|
|
ports:
|
|
- "127.0.0.1:9090:9090"
|
|
volumes:
|
|
- ./config:/etc/headscale
|
|
- ./lib:/var/lib/headscale
|
|
- ./run:/var/run/headscale
|
|
healthcheck:
|
|
test: ["CMD", "headscale", "health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 5
|
|
labels:
|
|
- "traefik.enable=true"
|
|
# Headscale API at /
|
|
- "traefik.http.routers.headscale.rule=Host(`headscale.rozic-dev.com`)"
|
|
- "traefik.http.routers.headscale.entrypoints=websecure"
|
|
- "traefik.http.routers.headscale.tls.certresolver=letsencrypt"
|
|
- "traefik.http.services.headscale.loadbalancer.server.port=8080"
|
|
|
|
headscale-ui:
|
|
<<: *default
|
|
image: ghcr.io/gurucomputing/headscale-ui:latest
|
|
container_name: headscale-ui
|
|
# UI listens on 8080 (and 8443) in the container by default
|
|
labels:
|
|
- "traefik.enable=true"
|
|
# Serve UI at /web on the *same* host to avoid CORS
|
|
- "traefik.http.routers.headscale-ui.rule=Host(`headscale.rozic-dev.com`) && PathPrefix(`/web`)"
|
|
- "traefik.http.routers.headscale-ui.entrypoints=websecure"
|
|
- "traefik.http.routers.headscale-ui.tls.certresolver=letsencrypt"
|
|
- "traefik.http.services.headscale-ui.loadbalancer.server.port=8080"
|
|
|
|
# 🔐 BASIC AUTH MIDDLEWARE
|
|
- "traefik.http.middlewares.headscale-ui-basicauth.basicauth.users=Dejan:$$2y$$05$$EAuwBj8Ac5YTRn90WSeQuezJxFZF0ghIC/mBlf6S.x8Bb/5jI49WC"
|
|
|
|
# Attach middleware to router
|
|
- "traefik.http.routers.headscale-ui.middlewares=headscale-ui-basicauth"
|
|
|
|
networks:
|
|
traefik:
|
|
external: true
|
|
name: traefik_default
|