Server

vim docker-compose.yml
-----
services:
  headscale:
    image: headscale/headscale:stable
    container_name: headscale
    volumes:
      - ./config:/etc/headscale
      - ./data:/var/lib/headscale
    ports:
      - 8081:8080
    command: serve
    restart: unless-stopped
  headscale-ui:
    image: ghcr.io/gurucomputing/headscale-ui:latest
    restart: unless-stopped
    container_name: headscale-ui
    ports:
      - 8080:8080
-----
# Download a example config file from github
mkdir -p ./config
wget https://raw.githubusercontent.com/juanfont/headscale/refs/heads/main/config-example.yaml -O ./config/config.yaml
## Here are the key configurations in this configuration file. 
### Please keep the default settings except these.
vim ./config/config.yaml
-----
server_url: https://yourdomain.com:443
listen_addr: 0.0.0.0:8080
 
dns:
  magic_dns: false
  base_domain: host.yourdomain.com
    global:
      - 114.114.114.114
      - 119.29.29.29
      # - 2606:4700:4700::1111
      # - 2606:4700:4700::1001
-----
vim /etc/caddy/Caddyfile
-----
yourdomain.com {
	log {
		output file /var/log/caddy/yourdomain.com.log {
			roll_size 100MiB
			roll_keep 7
			roll_keep_for 240h
			roll_gzip true
		}
	}
	encode zstd gzip
	reverse_proxy /web* http://127.0.0.1:8080
	reverse_proxy * http://127.0.0.1:8081
}
-----
vim ~/.zshrc
-----
alias headscale="docker exec headscale headscale"
-----

Add namespace

# Add a namespace (example: home)
headscale namespaces create home
 
# List namespaces
headscale namespaces list

Generate headscale api key

# Generate api key for headscale web ui
headscale apikeys create -e 720d

Visit https://yourdomain.com/web and set api key at configuration page.

Client

Start tailscale

# Registry node
tailscale up --login-server=https://yourdomain.com:443 --accept-routes=true --accept-dns=false --advertise-routes=192.168.123.0/24 --reset
 
# Then visit the terminal output url, then execute browser return command at headscale server
## Remanber to replace `USERNAME` to your namespace

Enable route (Server)

# (Server)
headscale routes list
headscale routes enable -r <route item number>