Tunnel Quick Reference
Tunnel Quick Reference
Quick commands and configurations for ngrok tunnel setup.
Installation
# macOSbrew install ngrok/ngrok/ngrok
# Linux (Ubuntu/Debian)curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | \ sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && \ echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | \ sudo tee /etc/apt/sources.list.d/ngrok.list && \ sudo apt update && sudo apt install ngrok
# Windowschoco install ngrok
# Verifyngrok versionOne-Time Setup
# 1. Get authtoken from https://dashboard.ngrok.com/get-started/your-authtoken# 2. Configure authtokenngrok config add-authtoken YOUR_TOKEN_HERE
# 3. Verifycat ~/.config/ngrok/ngrok.yml | grep authtokenBasic Commands
# Start tunnel on port 8000ngrok http 8000
# Start tunnel with specific regionngrok http 8000 --region us # Options: us, eu, ap, au, sa, jp, in
# Start tunnel with custom subdomain (paid plan)ngrok http 8000 --subdomain my-api-dev
# Start tunnel with custom domain (paid plan)ngrok http 8000 --hostname api.yourdomain.com
# Start tunnel with basic auth (paid plan)ngrok http 8000 --basic-auth "username:password"
# Start specific named tunnelngrok start python-saas
# Start multiple named tunnels (paid plan)ngrok start python-saas react-client rails-api
# Check versionngrok version
# View helpngrok http --helpProcess Management
# Check if ngrok is runningps aux | grep ngrok
# Stop all ngrok processespkill ngrok
# Stop specific ngrok processkill <PID>
# Run in backgroundngrok http 8000 > /dev/null &
# View ngrok processes with PIDspgrep -l ngrokConfiguration File
Location: ~/.config/ngrok/ngrok.yml
Basic Config
version: "2"authtoken: YOUR_TOKEN_HERE
tunnels: python-saas: proto: http addr: 8000
react-client: proto: http addr: 5173
rails-api: proto: http addr: 3000Advanced Config
version: "2"authtoken: YOUR_TOKEN_HEREregion: usconsole_ui: truelog_level: infolog_format: jsonlog: /var/log/ngrok.log
tunnels: python-saas: proto: http addr: 8000 inspect: true bind_tls: true host_header: rewrite subdomain: my-api-dev # Paid plan
# IP restrictions (paid plan) ip_restriction: allow_cidrs: - 203.0.113.0/24
# Basic auth (paid plan) basic_auth: - "admin:secretpass"Get Tunnel URL
From Terminal Output
ngrok http 8000# Look for "Forwarding" line:# Forwarding https://abc123.ngrok-free.app -> http://localhost:8000Using API
# Get tunnel info as JSONcurl -s http://localhost:4040/api/tunnels
# Extract just the URLcurl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url'
# Get HTTPS URL onlycurl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[] | select(.proto=="https") | .public_url'Web Inspection UI
# Access ngrok Web UI (when tunnel is running)open http://127.0.0.1:4040
# Or in browsercurl http://127.0.0.1:4040Features:
- View all requests/responses
- Replay requests
- Edit and replay modified requests
- Filter by path, status, method
- View timing and metrics
Common Debugging
Check Local Server
# Verify server is running on portlsof -i :8000
# Test endpoint locallycurl http://localhost:8000/health
# Check what's listening on portnetstat -an | grep 8000Check ngrok Status
# View ngrok logs (in terminal where ngrok is running)# Look for error messages
# Check ngrok service statuscurl -s https://status.ngrok.com/api/v2/status.json | jq .
# Test tunnel externallycurl https://YOUR_TUNNEL_URL.ngrok-free.app/healthReset Configuration
# Remove config filerm ~/.config/ngrok/ngrok.yml
# Re-add authtokenngrok config add-authtoken YOUR_NEW_TOKEN
# Testngrok http 8000Webhook URL Formats
PactaPay Webhook
https://YOUR_SUBDOMAIN.ngrok-free.app/api/commerce/webhooks/pactapayShopify Webhook
https://YOUR_SUBDOMAIN.ngrok-free.app/api/commerce/webhooks/shopifyGitHub Webhook
https://YOUR_SUBDOMAIN.ngrok-free.app/webhooks/githubGeneric Format
https://YOUR_SUBDOMAIN.ngrok-free.app/your/endpoint/pathDocker Integration
Run ngrok Outside Docker
# Start Docker servicesdocker-compose up -d
# Check which port is exposeddocker-compose ps
# Start ngrok pointing to exposed portngrok http 8000Run ngrok Inside Docker
services: api: build: ./templates/python-saas ports: - "8000:8000"
ngrok: image: ngrok/ngrok:alpine command: http api:8000 environment: - NGROK_AUTHTOKEN=${NGROK_AUTHTOKEN} ports: - "4040:4040"# Get tunnel URL from Dockerdocker exec -it <ngrok-container> sh -c \ "wget -qO- http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url'"
# Or use host curlcurl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url'Environment Variables
# Set authtoken via environment (alternative to config file)export NGROK_AUTHTOKEN=YOUR_TOKEN_HEREngrok http 8000
# Set regionexport NGROK_REGION=usngrok http 8000
# Disable inspect UIexport NGROK_INSPECT=falsengrok http 8000Troubleshooting Quick Checks
Connection Refused
# Check server is runninglsof -i :8000
# Start server if not runningcd templates/python-saas && python src/ui/main.py &
# Then try ngrok againngrok http 8000Invalid Authtoken
# Reset configrm ~/.config/ngrok/ngrok.ymlngrok config add-authtoken NEW_TOKEN_HEREngrok http 8000Account Limit Reached
# Kill all ngrok processespkill ngrok
# Verify no processes runningps aux | grep ngrok
# Start new tunnelngrok http 8000Webhook Returns 404
# Verify endpoint exists locallycurl http://localhost:8000/api/commerce/webhooks/pactapay
# Check route in codecd templates/python-saasgrep -r "webhooks/pactapay" src/
# Ensure path matches exactlyWebhook Returns 401
# Check webhook secret is configuredcat .env | grep WEBHOOK_SECRET
# Verify secret matches provider dashboard# PactaPay: https://dashboard.pactapay.com/webhooks
# Reload environmentsource .env && python src/ui/main.pyUseful Scripts
Auto-Extract Tunnel URL
#!/bin/bashwhile true; do URL=$(curl -s http://localhost:4040/api/tunnels 2>/dev/null | jq -r '.tunnels[0].public_url' 2>/dev/null) if [ "$URL" != "null" ] && [ -n "$URL" ]; then echo $URL break fi sleep 1doneUsage:
chmod +x get_ngrok_url.sh./get_ngrok_url.shAuto-Configure Webhook
#!/bin/bash# Get ngrok URLNGROK_URL=$(curl -s http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url')
if [ -z "$NGROK_URL" ] || [ "$NGROK_URL" == "null" ]; then echo "Error: ngrok not running or tunnel not found" exit 1fi
# Construct webhook URLWEBHOOK_URL="${NGROK_URL}/api/commerce/webhooks/pactapay"
echo "Webhook URL: $WEBHOOK_URL"echo ""echo "Configure in PactaPay Dashboard:"echo "https://dashboard.pactapay.com/webhooks"Usage:
chmod +x auto_webhook_pactapay.sh./auto_webhook_pactapay.shFree Plan Limits
- Tunnels: 1 simultaneous
- Rate: 40 requests/minute
- URLs: Random (changes on restart)
- Connections: Up to 10 per minute
- Tunnel lifetime: No limit (but URL changes)
Upgrade for:
- Multiple simultaneous tunnels
- Custom subdomains
- Reserved domains
- IP restrictions
- Basic auth
Pricing: https://ngrok.com/pricing
Keyboard Shortcuts (in ngrok terminal)
Ctrl+C: Stop tunnel- No other interactive commands (ngrok runs in foreground)
Common Ports
| Service | Default Port | Tunnel Command |
|---|---|---|
| FastAPI / Python SaaS | 8000 | ngrok http 8000 |
| React / Vite | 5173 | ngrok http 5173 |
| Rails API | 3000 | ngrok http 3000 |
| Rails UI Kit | 3001 | ngrok http 3001 |
| Data Pipeline (dbt docs) | 8081 | ngrok http 8081 |
| Static Landing (Astro) | 3002 | ngrok http 3002 |
| PostgreSQL | 5432 | ngrok tcp 5432 |
| Redis | 6379 | ngrok tcp 6379 |
Alternative Tunneling Tools
| Tool | Free Tier | Custom Domains | Open Source |
|---|---|---|---|
| ngrok | 1 tunnel, 40 req/min | Paid | No |
| Cloudflare Tunnel | Unlimited | Yes | No |
| localtunnel | Unlimited | No | Yes |
| serveo | Unlimited | No | Yes |
| Tailscale Funnel | Yes | Yes | No |
Additional Resources
- Full Guide: Tunnel Configuration Guide
- Webhook Troubleshooting: Webhook Failures Guide
- ngrok Docs: https://ngrok.com/docs
- ngrok Pricing: https://ngrok.com/pricing
- ngrok Status: https://status.ngrok.com
- Web UI (when running): http://127.0.0.1:4040
Last Updated: February 28, 2026 Maintainer: Seed & Source Team