# Makefile for Headscale Docker development environment .PHONY: help help: ## Show this help message @echo "Headscale Docker Development Environment" @echo "" @echo "Usage: make [target]" @echo "" @echo "Targets:" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " %-20s %s\n", $$1, $$2}' .PHONY: up up: ## Start all services docker compose up -d @echo "Waiting for Headscale to be healthy..." @sleep 10 @make setup .PHONY: down down: ## Stop and remove all services docker compose down .PHONY: clean clean: down ## Clean up everything including volumes docker compose down -v rm -f .env .PHONY: setup setup: ## Setup Headscale users and generate auth keys ./scripts/setup-headscale.sh .PHONY: restart-clients restart-clients: ## Restart Tailscale clients docker compose restart tailscale-client1 tailscale-client2 .PHONY: logs logs: ## Show logs from all services docker compose logs -f .PHONY: logs-headscale logs-headscale: ## Show Headscale server logs docker compose logs -f headscale .PHONY: logs-clients logs-clients: ## Show Tailscale client logs docker compose logs -f tailscale-client1 tailscale-client2 .PHONY: status status: ## Show status of all nodes @echo "=== Headscale Node Status ===" @docker exec headscale-server headscale nodes list || echo "No nodes registered yet" @echo "" @echo "=== Client1 Status ===" @docker exec tailscale-client1 tailscale status 2>/dev/null || echo "Client1 not ready" @echo "" @echo "=== Client2 Status ===" @docker exec tailscale-client2 tailscale status 2>/dev/null || echo "Client2 not ready" .PHONY: ping-test ping-test: ## Test connectivity between clients @echo "Testing connectivity from Client1 to Client2..." @docker exec tailscale-client1 tailscale ping client2 || echo "Ping failed - clients may not be connected yet" @echo "" @echo "Testing connectivity from Client2 to Client1..." @docker exec tailscale-client2 tailscale ping client1 || echo "Ping failed - clients may not be connected yet" .PHONY: shell-headscale shell-headscale: ## Open shell in Headscale container docker exec -it headscale-server /bin/sh .PHONY: shell-client1 shell-client1: ## Open shell in Client1 container docker exec -it tailscale-client1 /bin/sh .PHONY: shell-client2 shell-client2: ## Open shell in Client2 container docker exec -it tailscale-client2 /bin/sh .PHONY: build-local build-local: ## Build Headscale from local source cd .. && docker build -t headscale:local -f Dockerfile . @echo "To use local build, update docker-compose.yml:" @echo " image: headscale:local" .PHONY: register-manual register-manual: ## Show manual registration instructions @echo "=== Manual Node Registration ===" @echo "" @echo "1. Get node key from client:" @echo " docker exec tailscale-client1 tailscale up --login-server=http://headscale:8080" @echo "" @echo "2. Register the node:" @echo " docker exec headscale-server headscale nodes register --user testuser --key " @echo "" @echo "3. Verify registration:" @echo " make status" .PHONY: test-web test-web: ## Test web server connectivity through Tailscale @echo "Starting web server test..." @echo "Creating test content..." @mkdir -p www @echo "

Hello from Headscale Test Environment!

" > www/index.html @echo "Testing HTTP access from Client1 to web server..." @docker exec tailscale-client1 wget -q -O- http://webserver || echo "Web test failed"