gotunnel Documentation

gotunnel is an open-source, self-hostable tunneling tool. Expose local dev servers to the internet via a relay server, or create local HTTPS domains — all from one CLI.

Two modes: Use gotunnel expose for public URLs (like ngrok, self-hosted). Use gotunnel start for local .local domains (HTTPS on your machine).

Installation

Homebrew (macOS/Linux):

brew tap v1truv1us/gotunnel
brew install gotunnel

Go Install:

go install github.com/v1truv1us/gotunnel/cmd/gotunnel@latest

Install Script:

curl -sSL https://raw.githubusercontent.com/v1truv1us/gotunnel/main/scripts/install.sh | bash

Quick Start

Option A: Cloud Relay (public URL)

Requires a relay server (see Self-Hosting below). Works from any device.

gotunnel expose -p 3000 -d myapp --relay tunnel.yourdomain.com

# Output:
#   Local:   http://localhost:3000
#   Public:  https://myapp.tunnel.yourdomain.com

Option B: Local Tunnel (HTTPS on your machine)

No server needed. One-time setup for port-free URLs:

# One-time: install privileged helper (port 80/443 forwarding + DNS)
sudo gotunnel install-helper

# Start a tunnel
gotunnel start -p 3000 -d myapp

# Output:
#   Access:  https://myapp.local

Expose Command (Cloud Relay)

Connects to a relay server via WebSocket. The relay forwards public traffic to your local machine.

gotunnel expose -p 3000 -d myapp --relay tunnel.yourdomain.com

Flags:

  • -p, --port — local port to expose (default: 8080)
  • -d, --domain — subdomain for the public URL
  • -r, --relay — relay server URL

Auto-reconnects on disconnect. Press Ctrl+C to stop.

Self-Hosting the Relay

Deploy the relay server on your own infrastructure. Works with Docker, Coolify, or any VPS.

Docker

docker build -f Dockerfile.relay -t gotunnel-relay .
docker run -p 8080:8080 -e RELAY_DOMAIN=tunnel.example.com gotunnel-relay

Coolify

  1. Create project → Dockerfile → path: /Dockerfile.relay
  2. Set domain: tunnel.yourdomain.com
  3. Enable wildcard domain: *.{domain}
  4. Set env var: RELAY_DOMAIN=tunnel.yourdomain.com
  5. Deploy

DNS Setup

A    tunnel.yourdomain.com     → server IP
A    *.tunnel.yourdomain.com  → server IP

Relay API

  • GET /health — health check
  • GET /api/tunnels — list connected tunnels
  • WS /ws?domain=... — WebSocket tunnel endpoint

Local Tunnels

Create local HTTPS domains for development. Uses .local with SNI-based TLS proxy and mkcert certificates.

# Start daemon (auto-starts on first tunnel)
gotunnel daemon

# Create tunnels
gotunnel start -p 3000 -d frontend    # → https://frontend.local
gotunnel start -p 8080 -d api         # → https://api.local

# Manage
gotunnel list                         # Show active tunnels
gotunnel stop frontend                # Stop specific tunnel
gotunnel stop-all                     # Stop everything

Daemon Mode

The daemon runs persistently with a macOS menu bar icon. Tunnels survive terminal closure.

# Start daemon manually (or it auto-starts on first 'gotunnel start')
gotunnel daemon

# Menu bar shows:
#   🚇 Active tunnels (2)
#   ● https://frontend.local     [click to copy]
#   ● https://api.local          [click to copy]
#   ⏹ Stop frontend
#   ⏹ Stop api
#   ⏹ Stop All
#   Quit gotunnel

The daemon auto-starts when you run gotunnel start if it's not already running.

Privileged Helper

One-time setup for port-free URLs (80→8080, 443→8443) and automatic /etc/hosts management.

# Install (one-time, macOS/Linux)
sudo gotunnel install-helper

# Uninstall
sudo gotunnel uninstall-helper

The helper runs as a system service (launchd on macOS, systemd on Linux) and:

  • Forwards port 80→8080 and 443→8443
  • Manages /etc/hosts entries for .local domains
  • Resolves *.local DNS queries for network devices

CLI Reference

COMMANDS:
   expose    Expose a local port via relay server
   start     Start a local HTTPS tunnel
   stop      Stop a specific tunnel
   list      List active tunnels
   stop-all  Stop all tunnels
   daemon    Start daemon with menu bar icon
   install-helper    Install privileged port forwarder (sudo)
   uninstall-helper  Remove privileged port forwarder (sudo)

GLOBAL OPTIONS:
   --proxy value        Proxy mode: builtin, auto, none [$GOTUNNEL_PROXY]
   --proxy-http-port    HTTP port (default: 8080)
   --proxy-https-port   HTTPS port (default: 8443)
   --debug              Enable debug logging [$DEBUG]
   --sentry-dsn         Sentry DSN (opt-in) [$GOTUNNEL_SENTRY_DSN]

Environment Variables

VariableDescriptionDefault
RELAY_DOMAINBase domain for relay server—
RELAY_ADDRRelay listen address:8080
GOTUNNEL_PROXYLocal proxy modeauto
GOTUNNEL_SENTRY_DSNSentry error tracking (opt-in)disabled
DEBUGEnable debug loggingfalse

Common Issues

Mobile device can't resolve .local domain

iOS browsers don't resolve .local via mDNS. Use the relay server (gotunnel expose) for mobile testing, or access via the Mac's IP address.

Certificate warning in browser

gotunnel uses self-signed certificates via mkcert. To trust them locally:

mkcert -install

For mobile devices, accept the certificate warning or use the relay server (which uses your server's TLS).

Port 8080 already in use

Another process is using the proxy port. Use --proxy-http-port 9080 to change it, or --proxy=none to skip the proxy.

Relay connection refused

Check that the relay server is running and the domain is correct. The client auto-reconnects every 3 seconds.

Need help? Open an issue on GitHub.