henryavila / laravel-serve-ngrok
Serve a Laravel app through an ngrok tunnel with APP_URL/ASSET_URL rewriting and session recovery helpers
Requires
- php: ^8.2
- illuminate/console: ^11.0|^12.0
- illuminate/http: ^11.0|^12.0
- illuminate/process: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.17
- mockery/mockery: ^1.6
- orchestra/testbench: ^9.0|^10.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
README
Serve a Laravel app through an ngrok tunnel with one Artisan command.
It starts ngrok, discovers the public HTTPS URL, and runs php artisan serve with:
APP_URL/ASSET_URLset to the tunnel URL (so generated links work)TRUSTED_PROXIES=*(so HTTPS / X-Forwarded-* headers work)
When the free-plan session limit (ERR_NGROK_108) is hit, the command lists online agent sessions and prints exact kill commands (CLI + Artisan).
Requirements
- PHP 8.2+
- Laravel 11 or 12
- ngrok CLI installed and on
PATH(or pass--ngrok-bin) - ngrok authtoken configured (
ngrok config add-authtoken …) - For session list/stop helpers: an API key (free) via
ngrok config add-api-key …
Installation
composer require henryavila/laravel-serve-ngrok --dev
Laravel auto-discovers the service provider. No config publish required.
Packagist: https://packagist.org/packages/henryavila/laravel-serve-ngrok
Source: https://github.com/henryavila/laravel-serve-ngrok
Usage
php artisan serve:ngrok php artisan serve:ngrok --host=127.0.0.1 --port=8000 php artisan serve:ngrok --ngrok-bin=/usr/local/bin/ngrok --timeout=20
Session management
Requires ngrok config add-api-key <KEY> (create at https://dashboard.ngrok.com/api-keys — free tier).
# List online agent sessions + exact kill commands php artisan serve:ngrok --list-sessions # Stop one or more sessions php artisan serve:ngrok --stop-session=ts_xxx php artisan serve:ngrok --stop-session=ts_a,ts_b # Stop every online session php artisan serve:ngrok --stop-all-sessions
Equivalent raw ngrok CLI:
ngrok api tunnel-sessions list ngrok api tunnel-sessions stop ts_xxx
Production guard
The command refuses to run when APP_ENV=production.
Security defaults
- Public URL — only HTTPS URLs on official ngrok host suffixes (
*.ngrok-free.app,*.ngrok.io, …) are accepted asAPP_URL/ASSET_URL. - Session IDs —
--stop-sessionmust matchts_[A-Za-z0-9_-]+before any CLI call. - Bind address —
--hostis limited to loopback (127.0.0.1,::1,localhost).0.0.0.0/ LAN hosts are rejected.
How it works
- Starts
ngrok http http://{host}:{port} - Polls the local agent API
http://127.0.0.1:4040/api/tunnelsfor an HTTPSpublic_url - Starts
php artisan servewith tunnel-aware env vars - On Ctrl+C (or process exit), stops both Laravel and ngrok
If ngrok dies with ERR_NGROK_108 (max simultaneous agents), the command:
- Prints ngrok stderr
- Lists sessions via
ngrok api tunnel-sessions list - Prints copy-paste kill commands for one / many / all
Testing this package
composer install
composer test
License
MIT