How to expose localhost:8000 to the internet
Most guides assume port 3000. Django's built-in dev server defaults to 8000. Laravel and FastAPI often sit here as well. This page is for 8000 specifically.
Django's built-in dev server defaults to 8000. Laravel and FastAPI often sit here as well. The tunnel does not care what framework you run. It forwards HTTPS to whatever is bound on 8000.
Quick start
curl -fsSL https://get.ngsrv.com | bash
ngsrv token <YOUR_TOKEN>
ngsrv http 8000
You get a public URL like https://furry-otter-1842.tnl.ngsrv.com that routes to http://localhost:8000.
What usually runs on 8000
- Django
- Laravel (php artisan serve)
- FastAPI (uvicorn default)
Typical dev command: python manage.py runserver
Install the CLI
# macOS (Homebrew)
brew install ngsrv/tap/ngsrv
# macOS / Linux
curl -fsSL https://get.ngsrv.com | bash
# Windows (PowerShell)
irm https://get.ngsrv.com/windows | iex
Sign up at ngsrv.com/register if you need a token. Free tier, no card.
Run the tunnel
With your server already up on port 8000:
ngsrv http 8000
Sample output:
forwarding https://furry-otter-1842.tnl.ngsrv.com -> http://localhost:8000
status online
Stable subdomain (optional)
Random names change when you restart. For webhooks or client previews, reserve one:
ngsrv http 8000 --subdomain api-dev
# -> https://api-dev.tnl.ngsrv.com
Host header gotcha
Django checks ALLOWED_HOSTS. A public hostname will get blocked until you add it.
Add the ngsrv hostname (or * for quick local testing) to ALLOWED_HOSTS in settings.py.
When it breaks
connection refused — Nothing is listening on 8000. Confirm with lsof -i :8000 (macOS/Linux) or netstat -ano | findstr :8000 (Windows).
401 invalid token — Re-run ngsrv token <YOUR_TOKEN> from the dashboard.
Tunnel drops — ngsrv reconnects on its own. Persistent drops usually mean VPN or proxy interference.