- HTTPS with no Nginx, Caddy, or Let’s Encrypt setup
- No public inbound ports required — the VM only makes outbound connections
- Free on Cloudflare’s free plan
- Pairs naturally with GCP VMs running Gmail-integrated apps (same Google Cloud project)
Prerequisites
- A Google Cloud account with billing enabled
- A Cloudflare account (free tier) with a domain managed by Cloudflare DNS
- SSH access to GCP (via
gcloudCLI or browser-based SSH)
1. Create the Compute Engine VM
- Go to Compute Engine → VM instances → Create instance
- Name:
inbox-zero(or your choice) - Region/Zone: choose one close to your users
- Machine configuration:
- Minimum:
e2-medium(2 vCPU, 4 GB RAM) — add swap if using this size - Recommended:
e2-standard-2(2 vCPU, 8 GB RAM)
- Minimum:
- Boot disk:
- OS: Debian 12 or Ubuntu 24.04 LTS
- Size: 20 GB minimum (Docker images + logs)
- Firewall: leave HTTP and HTTPS checkboxes unchecked — Cloudflare Tunnel handles all ingress
- Click Create
Optional: Reserve a static external IP
GCP external IPs change if the VM is stopped. If you need SSH access from a fixed address, reserve a static IP under VPC network → IP addresses and attach it to the VM. Cloudflare Tunnel does not require a static IP.2. Install Docker and Docker Compose
SSH into the VM and run:Add swap (required for e2-medium)
If you’re usinge2-medium (4 GB RAM), add swap to avoid OOM kills:
3. Set Up Cloudflare Tunnel
Create the tunnel
In the Cloudflare dashboard:- Go to Zero Trust → Networks → Tunnels → Add a tunnel
- Choose Cloudflared as the connector type
- Name the tunnel (e.g.
inbox-zero) - Follow the install instructions for Debian — copy the
cloudflaredinstall command shown in the dashboard and run it on your VM:
- Run the service install command shown in the dashboard. It looks like:
cloudflared as a systemd service that starts automatically on boot.
Configure the public hostname
Back in the Cloudflare dashboard tunnel settings:- Go to the Public Hostnames tab
- Click Add a public hostname
- Subdomain: e.g.
inbox(resulting ininbox.yourdomain.com) - Domain: your Cloudflare-managed domain
- Service:
http://localhost:3000 - Save — Cloudflare automatically adds a CNAME DNS record
https://inbox.yourdomain.com once the tunnel is running and the app is started.
4. Set Up Inbox Zero
Option A: CLI (recommended)
https://inbox.yourdomain.com).
Option B: Manual
5. Start the Application
6. Update Google OAuth Redirect URIs
In Google Cloud Console → APIs & Services → Credentials, open your OAuth client and add:Maintenance
Restart after a VM reboot
Both Docker (with--restart unless-stopped / Compose) and cloudflared run as systemd services and restart automatically. Verify with:
Update to the latest image
View logs
Troubleshooting
Tunnel shows as “Healthy” but site returns 502:- The app container may still be starting up — wait 60 seconds and refresh
- Check
docker logs inbox-zero-services-web-1for startup errors
- Check
journalctl -u cloudflaredfor errors - Verify the VM has outbound internet access (should work by default on GCP)
- Ensure
NEXT_PUBLIC_BASE_URLexactly matches the redirect URI registered in Google Cloud Console - Must match the Cloudflare hostname including
https://