Remote Access: Tailscale & WireGuard

← Self-Hosting · Foundations 4 of 8 · Replaces: opening ports / commercial VPN apps

What You'll Build

A VPN (virtual private network) makes your phone act as if it's on your home Wi-Fi, even on mobile data. That means you can use every app on this site from anywhere without exposing any of them to the internet.

TailscaleWireGuard (wg-easy)
Setup difficultyEasyMedium
Port forwardingNone — works through almost any networkOne UDP port (51820)
Depends on an outside companyYes, for login/coordination (your traffic is still end-to-end encrypted)No — 100% yours
Works behind CGNAT / mobile-broadband home internetYesUsually no

Start with Tailscale. Come back for WireGuard if you want zero outside dependencies.

Option A: Tailscale (Recommended)

A1. Install on the server

curl -fsSL https://tailscale.com/install.sh | sh

# Join your tailnet AND share your whole home network (subnet router),
# so *.home.example.com names and other home devices work remotely
sudo tailscale up --advertise-routes=192.168.1.0/24

# Required for subnet routing: allow the server to forward traffic
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

Open the login link it prints and sign in (Google, Microsoft, GitHub, or Apple account).

A2. Approve the subnet route

  1. Go to the Tailscale admin console → Machines → your server → ⋯ → Edit route settings.
  2. Tick 192.168.1.0/24 → Save.
  3. While you're there: ⋯ → Disable key expiry for the server, so it never logs itself out.

A3. Install on your phone and laptop

Install the Tailscale app from your app store, sign in with the same account, and switch it on. Test on mobile data: open https://portainer.home.example.com — it loads as if you were home.

Use your own ad-blocking DNS everywhere: in the admin console → DNS → Add nameserver → Custom, enter your server's IP (192.168.1.50) and tick Override local DNS. Your phone now uses Pi-hole or AdGuard Home wherever you are.

Option B: Self-Hosted WireGuard with wg-easy

wg-easy runs a WireGuard VPN server with a web page for adding devices and showing QR codes.

B1. Start it with the official compose file

mkdir -p ~/stacks/wg-easy && cd ~/stacks/wg-easy

# Download the project's own, up-to-date compose file
curl -o compose.yaml https://raw.githubusercontent.com/wg-easy/wg-easy/master/docker-compose.yml

# Look through it — it uses UDP 51820 (VPN) and TCP 51821 (web UI)
nano compose.yaml

By default the web UI expects to sit behind HTTPS. Since we'll only open it from home, un-comment the environment: block in the file and set INSECURE=true (or add it to Nginx Proxy Manager as wg.home.example.com → port 51821 and leave it off).

docker compose up -d

B2. Run the setup wizard

  1. Open http://192.168.1.50:51821 and create the admin account.
  2. For the host, enter your public IP — or better, a DNS name that points to it (e.g. vpn.example.com). Use a dynamic-DNS service if your home IP changes.

B3. Forward one port and add devices

  1. In your router, forward UDP 51820 to 192.168.1.50. Nothing else.
  2. In wg-easy, click + New client, name it (e.g. "Alex's phone"), and show the QR code.
  3. On the phone, install the official WireGuard app → + → Scan from QR code. Toggle it on and test on mobile data.

Troubleshooting

What's Next?

Before you trust the server with your photos and passwords, set up backups:

Foundations 5: Backups with restic →