# Tailscale Serve for Internal Services

Standard way to expose Docker services on app1 to the tailnet without public exposure.

## Setup

```bash
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh

# Authenticate — prints a URL to open in browser
tailscale up
```

Once authenticated, the server gets a `100.x.x.x` Tailscale IP:

```bash
tailscale status
```

## Expose a Service via Tailscale Serve

```bash
# Expose port 8080 (Vaultwarden) as HTTPS via Tailscale
tailscale serve --bg --https 443 --set-path / http://127.0.0.1:8080
```

This creates a URL like `https://<hostname>.tailc2f3b0.ts.net/` — only accessible within your tailnet, with a valid Tailscale TLS cert. No browser warnings.

## Rename Tailscale hostname

```bash
tailscale set --hostname <name>
```

The hostname becomes part of the Tailscale Serve URL.

## Switch URL without breaking the app

If DNS naming changes after Tailscale Serve is configured:

1. The service's DOMAIN env var in the Docker compose must match the Tailscale URL
2. Update the compose file, restart the container
3. The Bitwarden app on client devices needs the server URL updated to match

## UFW: Tailscale traffic only

```bash
# Allow only tailscale interface for internal services
ufw allow in on tailscale0 to any port 8080 proto tcp comment 'Service via Tailscale'

# Block public access
ufw delete allow 8080/tcp
ufw reload
```

## Best Practices

- Internal services do NOT need public DNS or Let's Encrypt — Tailscale Serve provides HTTPS automatically
- The Tailscale IP (`100.x.x.x`) changes if the node re-registers — always use the Tailscale domain name for stable references
- Tailscale must be running and authenticated before Serve will work
- On the standby/backup, Tailscale is optional but recommended for SSH access if public SSH is ever locked down

## Per-Device Setup

Install the Tailscale app on each device:
- **iPhone/iPad:** App Store → "Tailscale"
- **Mac:** [tailscale.com/download-mac](https://tailscale.com/download-mac)
- Login with the same identity provider as the server

## Pitfalls

- **HTTPS vs HTTP on iOS Bitwarden app:** The Bitwarden app for iOS sometimes has trouble with Tailscale Serve HTTPS URLs. Workaround is to clear the app's server config, force-close, and re-add. If the problem persists, the app may cache encryption parameters tied to the old server URL — delete and reinstall the app.
- **Hostname with zeros/Os:** If the Tailscale hostname contains `0` (zero) or `O` (letter O), the iOS Bitwarden app may confuse them when displaying the URL. Avoid this by choosing a hostname without ambiguous characters.
- **Server URL change invalidates login:** If the DOMAIN env var changes in Vaultwarden, users will get "username or password is incorrect" errors on existing client sessions even with the correct password. The client must be reconfigured with the new Server URL. The existing session on the old URL does not carry over — this is a client-side cache issue, not an actual password mismatch.
