Building a $0 VPS on Google Cloud: DietPi, Tailscale, IPv6, and the traps I hit
Description and use
The author successfully built a zero‑cost VPS that meets all constraints, but encountered five major traps: DietPi conversion script removing Tailscale, GCP image naming requirement, unintended public IPv4 and default password, lack of IPv6 egress, and IPv4‑only destination reachability. Workarounds included using a custom image, configuring IPv6 manually, and deploying a proxy on a dual‑stack peer.
Problem
Create a small, always‑on Linux VM on Google Cloud that is reachable only via Tailscale, has no public IPv4, and costs zero dollars per month.
Outcome
The author successfully built a zero‑cost VPS that meets all constraints, but encountered five major traps: DietPi conversion script removing Tailscale, GCP image naming requirement, unintended public IPv4 and default password, lack of IPv6 egress, and IPv4‑only destination reachability. Workarounds included using a custom image, configuring IPv6 manually, and deploying a proxy on a dual‑stack peer.
Workflow
- Create a new GCE instance from a custom DietPi image, ensuring the image file is named disk.raw and UEFI_COMPATIBLE is set.
- Configure the instance to use a custom VPC with IPV4_IPV6 stack and no external IPv4 address.
- Install Tailscale and verify connectivity via tailscale status and ping.
- Set up IPv6 networking by adding a static IPv6 address and gateway in /etc/network/interfaces.d/eth0.conf.
- Create a CONNECT proxy on a dual‑stack Tailscale peer and configure apt and curl to use it for IPv4‑only hosts.
- Enable budget‑triggered shutdown via Cloud Billing.
- Verify that the VM can reach IPv6‑only and IPv4‑only destinations as intended.
Evidence
"The script’s own header says it plainly: # - Either Ethernet connection or local (non-SSH) terminal access"
"GCP only accepts a file literally named disk.raw"
"The VM came up with a public IP and a default password"
"tailscale status on the peer still showed the node as active, with tx/rx counters"
"IPv4-only destinations remained out of reach"
- Record date: 2026-10-25T22:26:18.978Z