services: # Headscale control server headscale: image: headscale/headscale:latest container_name: headscale-server volumes: - ./headscale-config.yaml:/etc/headscale/config.yaml - ./acl.hujson:/etc/headscale/acl.hujson - headscale-data:/var/lib/headscale ports: - "8180:8080" # HTTP API - "9090:9090" # Metrics - "50443:50443" # gRPC command: serve restart: unless-stopped networks: headscale-net: ipv4_address: 10.99.0.10 healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"] interval: 5s timeout: 3s retries: 5 start_period: 10s # Tailscale client 1 tailscale-client1: image: tailscale/tailscale:latest container_name: tailscale-client1 hostname: client1 cap_add: - NET_ADMIN - SYS_MODULE environment: - TS_STATE_DIR=/var/lib/tailscale - TS_EXTRA_ARGS=--login-server=http://headscale:8080 - TS_HOSTNAME=client1 - TS_AUTHKEY=${TS_AUTHKEY_CLIENT1:-} - TS_ACCEPT_ROUTES=true - TS_USERSPACE=false volumes: - tailscale-client1-state:/var/lib/tailscale - /dev/net/tun:/dev/net/tun - ./scripts/client-init.sh:/usr/local/bin/client-init.sh:ro networks: headscale-net: ipv4_address: 10.99.0.21 depends_on: - headscale restart: unless-stopped command: sh -c "tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/var/run/tailscale/tailscaled.sock --tun=userspace-networking & sleep 5 && /usr/local/bin/client-init.sh client1 && wait" # Tailscale client 2 tailscale-client2: image: tailscale/tailscale:latest container_name: tailscale-client2 hostname: client2 cap_add: - NET_ADMIN - SYS_MODULE environment: - TS_STATE_DIR=/var/lib/tailscale - TS_EXTRA_ARGS=--login-server=http://headscale:8080 - TS_HOSTNAME=client2 - TS_AUTHKEY=${TS_AUTHKEY_CLIENT2:-} - TS_ACCEPT_ROUTES=true - TS_USERSPACE=false volumes: - tailscale-client2-state:/var/lib/tailscale - /dev/net/tun:/dev/net/tun - ./scripts/client-init.sh:/usr/local/bin/client-init.sh:ro networks: headscale-net: ipv4_address: 10.99.0.22 depends_on: - headscale restart: unless-stopped command: sh -c "tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/var/run/tailscale/tailscaled.sock --tun=userspace-networking & sleep 5 && /usr/local/bin/client-init.sh client2 && wait" # Optional: A simple web server for testing connectivity test-webserver: image: nginx:alpine container_name: test-webserver hostname: webserver networks: headscale-net: ipv4_address: 10.99.0.30 volumes: - ./www:/usr/share/nginx/html:ro restart: unless-stopped networks: headscale-net: driver: bridge ipam: config: - subnet: 10.99.0.0/24 gateway: 10.99.0.1 volumes: headscale-data: tailscale-client1-state: tailscale-client2-state: