Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Ngrok with Laravel Sail on Windows/WSL2

Laravel Sail on Windows/WSL2 works great until you need to expose your site to the internet. You'll need this for testing webhooks, showing clients your work, or testing on different devices. The built-in sail share command and expose.dev both fail consistently on Windows/WSL2. This guide shows you how to use Ngrok instead, which actually works.

Laravel's Built-in Options Don't Work

The Problem with sail share

Two reasons sail share sucks on Windows/WSL2:

  1. It just breaks: The command flat-out fails most of the time in Windows/WSL2.
  2. No HTTPS: Taylor Otwell himself has mentioned that sail share doesn't handle HTTPS termination properly. It gives you HTTP URLs, which are useless for testing modern webhooks that require HTTPS.

Trying expose.dev Directly Isn't Better

I tried using the expose.dev client directly:

  1. Endless loading: The URL just loads forever without showing your site.
  2. No useful errors: Good luck figuring out what's wrong.
  3. Mac-first development: Expose seems built for macOS/Herd, with Windows/WSL2/Sail users as an afterthought.

Ngrok Just Works

Ngrok solves all these problems:

  1. Fast setup: Takes less than 2 minutes to get running.
  2. It actually works: No cryptic errors, just immediate results.
  3. HTTPS built-in: Gets you proper HTTPS URLs immediately.
  4. Free tier works fine: Plenty of bandwidth for development and testing.

Setting Up Ngrok with Laravel Sail on Windows/WSL2

Fixing the One Annoying Issue: Mixed Content

There's only one problem to fix. Ngrok serves your site over HTTPS, but your Sail app inside Docker thinks it's on HTTP (port 80). This makes Laravel generate asset URLs with http://, causing browsers to block assets due to "mixed content" errors.

Here's how to fix it with a simple middleware:

1. Create the Middleware:

Create a file at app/Http/Middleware/UpgradeToHttpsUnderNgrok.php:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Symfony\Component\HttpFoundation\Response;

class UpgradeToHttpsUnderNgrok
{
    public function handle(Request $request, Closure $next): Response
    {
        // Check if the request is coming through a known ngrok domain suffix
        // Added .ngrok.io as another common suffix besides the free tier one
        if (str_ends_with($request->getHost(), '.ngrok-free.app') || str_ends_with($request->getHost(), '.ngrok.io')) {
            URL::forceScheme('https');
        }

        return $next($request);
    }
}

2. Register the Middleware:

Add the middleware to your web group in bootstrap/app.php:

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    // ... other configurations ...
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->web(append: [
            // ... other web middleware ...
            \App\Http\Middleware\UpgradeToHttpsUnderNgrok::class, // Add this line
        ]);

        // ... other middleware groups ...
    })
    // ... exceptions, etc ...
    ->create();

Quick Ngrok Setup Steps

  1. Sign up: Go to ngrok.com and create an account.

  2. Install it: Open your WSL2 terminal and follow the Linux setup steps from https://dashboard.ngrok.com/get-started/setup/linux. You'll download the agent and add your auth token.

  3. Run it: Start your Laravel Sail app (sail up -d), then run:

    # Sail uses port 80 by default
    ngrok http 80
  4. Use your URL: Ngrok gives you a URL like https://<random-string>.ngrok-free.app. Use this for webhooks, client demos, or whatever you need.

  5. Add the middleware: Make sure you've added the UpgradeToHttpsUnderNgrok middleware shown above to fix the mixed content errors.

The Bottom Line

If you're using Laravel Sail on Windows/WSL2 and need to share your site, skip the headaches with sail share and expose.dev. Just use Ngrok. It takes minutes to set up, gives you proper HTTPS URLs, and with the simple middleware fix above, it works perfectly with Sail. The free tier is more than enough for most development needs.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Subscribe to my newsletter

Get new posts when I publish them.

I respect your privacy. Unsubscribe at any time.

Leave a Reply

Your email address will not be published. Required fields are marked *