Sanitized mirror from private repository - 2026-03-08 09:25:17 UTC
This commit is contained in:
228
hosts/synology/calypso/headscale.yaml
Normal file
228
hosts/synology/calypso/headscale.yaml
Normal file
@@ -0,0 +1,228 @@
|
||||
# Headscale - Self-Hosted Tailscale Control Server
|
||||
# =============================================================================
|
||||
# Open-source implementation of the Tailscale control server
|
||||
# =============================================================================
|
||||
# Deployed via: Portainer GitOps
|
||||
# Ports: 8080 (HTTP API), 443 (HTTPS via NPM), 9090 (Metrics)
|
||||
#
|
||||
# Why Calypso?
|
||||
# - Already runs Authentik (SSO/OIDC provider) for seamless integration
|
||||
# - Already runs Nginx Proxy Manager for external HTTPS access
|
||||
# - Infrastructure services host (Gitea, NPM, Authentik)
|
||||
# - Synology NAS = always-on, stable, reliable
|
||||
# - Low resource requirements fit well alongside existing services
|
||||
#
|
||||
# External Access:
|
||||
# - Configure NPM to proxy headscale.vish.gg → headscale:8080
|
||||
# - OIDC auth via Authentik for user management
|
||||
#
|
||||
# Architecture:
|
||||
# ┌─────────────────────────────────────────────────────────────────────┐
|
||||
# │ HEADSCALE SETUP │
|
||||
# ├─────────────────────────────────────────────────────────────────────┤
|
||||
# │ │
|
||||
# │ ┌─────────────┐ ┌─────────────────────────┐ │
|
||||
# │ │ Clients │ │ Calypso │ │
|
||||
# │ │ │ │ │ │
|
||||
# │ │ ┌─────────┐ │ HTTPS/443 │ ┌───────────────────┐ │ │
|
||||
# │ │ │Tailscale│ │─────────────────────▶│ │ Nginx Proxy Mgr │ │ │
|
||||
# │ │ │ Client │ │ headscale.vish.gg │ │ (SSL Term) │ │ │
|
||||
# │ │ └─────────┘ │ │ └─────────┬─────────┘ │ │
|
||||
# │ │ │ │ │ │ │
|
||||
# │ │ ┌─────────┐ │ │ ▼ │ │
|
||||
# │ │ │ Phone │ │ │ ┌───────────────────┐ │ │
|
||||
# │ │ │ App │ │ │ │ Headscale │ │ │
|
||||
# │ │ └─────────┘ │ │ │ :8080 │ │ │
|
||||
# │ │ │ │ └─────────┬─────────┘ │ │
|
||||
# │ │ ┌─────────┐ │ │ │ │ │
|
||||
# │ │ │ Linux │ │ │ ▼ │ │
|
||||
# │ │ │ Server │ │ │ ┌───────────────────┐ │ │
|
||||
# │ │ └─────────┘ │ │ │ Authentik │ │ │
|
||||
# │ └─────────────┘ │ │ (OIDC Auth) │ │ │
|
||||
# │ │ └───────────────────┘ │ │
|
||||
# │ └─────────────────────────┘ │
|
||||
# └─────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
configs:
|
||||
headscale_config:
|
||||
content: |
|
||||
# Headscale Configuration
|
||||
# https://headscale.net/ref/configuration/
|
||||
|
||||
# Server URL - must be accessible from clients
|
||||
server_url: https://headscale.vish.gg
|
||||
|
||||
# Listen addresses
|
||||
listen_addr: 0.0.0.0:8080
|
||||
metrics_listen_addr: 0.0.0.0:9090
|
||||
grpc_listen_addr: 0.0.0.0:50443
|
||||
grpc_allow_insecure: false
|
||||
|
||||
# TLS disabled - handled by Nginx Proxy Manager
|
||||
tls_cert_path: ""
|
||||
tls_key_path: ""
|
||||
|
||||
# Key paths (auto-generated if not exist)
|
||||
private_key_path: /var/lib/headscale/private.key
|
||||
noise:
|
||||
private_key_path: /var/lib/headscale/noise_private.key
|
||||
|
||||
# IP address allocation for the Tailscale network
|
||||
# Using 100.64.0.0/10 (CGNAT range) - standard for Tailscale
|
||||
prefixes:
|
||||
v4: 100.64.0.0/10
|
||||
v6: fd7a:115c:a1e0::/48
|
||||
|
||||
# Allocate sequential IPs
|
||||
prefixes:
|
||||
allocation: sequential
|
||||
|
||||
# DERP (relay) servers
|
||||
# Using Tailscale's public DERP servers (free, reliable)
|
||||
# You can add custom DERP servers if needed
|
||||
derp:
|
||||
server:
|
||||
enabled: false # Don't run our own DERP
|
||||
region_id: 999
|
||||
region_code: "custom"
|
||||
region_name: "Custom DERP"
|
||||
stun_listen_addr: "0.0.0.0:3478"
|
||||
urls:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
paths: []
|
||||
auto_update_enabled: true
|
||||
update_frequency: 24h
|
||||
|
||||
# Disable ephemeral node inactivity timeout (keep nodes registered)
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
|
||||
# Database configuration - SQLite for simplicity
|
||||
database:
|
||||
type: sqlite
|
||||
sqlite:
|
||||
path: /var/lib/headscale/db.sqlite
|
||||
write_ahead_log: true
|
||||
|
||||
# OIDC Configuration - Authentik Integration
|
||||
# This allows users to authenticate via Authentik SSO
|
||||
oidc:
|
||||
only_start_if_oidc_is_available: true
|
||||
issuer: "https://sso.vish.gg/application/o/headscale/"
|
||||
client_id: "CHANGE_ME_CLIENT_ID"
|
||||
client_secret: "REDACTED_CLIENT_SECRET"
|
||||
|
||||
# What scopes to request
|
||||
scope: ["openid", "profile", "email"]
|
||||
|
||||
# Extra parameters for auth request
|
||||
extra_params:
|
||||
domain_hint: vish.gg
|
||||
|
||||
# Which domains/users are allowed
|
||||
allowed_domains:
|
||||
- vish.gg
|
||||
allowed_groups: []
|
||||
allowed_users: []
|
||||
|
||||
# Strip @domain from username
|
||||
strip_email_domain: true
|
||||
|
||||
# Token expiry
|
||||
expiry: 180d
|
||||
|
||||
# Use email as username
|
||||
use_expiry_from_token: false
|
||||
|
||||
# Logging configuration
|
||||
log:
|
||||
format: text
|
||||
level: info
|
||||
|
||||
# Disable telemetry
|
||||
logtail:
|
||||
enabled: false
|
||||
randomize_client_port: false
|
||||
|
||||
# DNS configuration for the Tailscale network
|
||||
dns:
|
||||
magic_dns: true
|
||||
base_domain: tail.vish.gg
|
||||
nameservers:
|
||||
global:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
search_domains: []
|
||||
extra_records: []
|
||||
|
||||
# Unix socket for CLI operations
|
||||
unix_socket: /var/run/headscale/headscale.sock
|
||||
unix_socket_permission: "0770"
|
||||
|
||||
# Policy configuration (ACLs)
|
||||
# Define who can access what in your network
|
||||
policy:
|
||||
mode: file
|
||||
path: "" # Empty = allow all (configure ACLs later)
|
||||
|
||||
services:
|
||||
headscale:
|
||||
image: headscale/headscale:latest
|
||||
container_name: headscale
|
||||
restart: unless-stopped
|
||||
configs:
|
||||
- source: headscale_config
|
||||
target: /etc/headscale/config.yaml
|
||||
volumes:
|
||||
# Persistent data (keys, database, socket)
|
||||
- headscale-data:/var/lib/headscale
|
||||
- headscale-socket:/var/run/headscale
|
||||
ports:
|
||||
# Main API port - proxied via NPM
|
||||
- "8085:8080"
|
||||
# gRPC port for API access
|
||||
- "50443:50443"
|
||||
# Metrics for Prometheus
|
||||
- "9099:9090"
|
||||
command: serve
|
||||
networks:
|
||||
- headscale-net
|
||||
# Connect to Authentik network for OIDC
|
||||
- authentik-net
|
||||
healthcheck:
|
||||
test: ["CMD", "headscale", "health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
# Headscale UI - Web interface for management
|
||||
# https://github.com/gurucomputing/headscale-ui
|
||||
headscale-ui:
|
||||
image: ghcr.io/gurucomputing/headscale-ui:latest
|
||||
container_name: headscale-ui
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
# URL of the Headscale API (from the UI's perspective)
|
||||
- HTTP_PORT=8080
|
||||
ports:
|
||||
- "8086:8080"
|
||||
networks:
|
||||
- headscale-net
|
||||
depends_on:
|
||||
headscale:
|
||||
condition: service_healthy
|
||||
|
||||
volumes:
|
||||
headscale-data:
|
||||
name: headscale-data
|
||||
headscale-socket:
|
||||
name: headscale-socket
|
||||
|
||||
networks:
|
||||
headscale-net:
|
||||
name: headscale-net
|
||||
driver: bridge
|
||||
# External network to reach Authentik
|
||||
authentik-net:
|
||||
external: true
|
||||
name: authentik-net
|
||||
Reference in New Issue
Block a user