Run a livewire laravel app behind a nginx reverse proxy

Tobias Etzold • April 5, 2023

linux laravel

For my web projects I'm using a Docker setup. Every single application is run as a docker container. To reach each of this containers, there is a nginx reverse proxy in place to route the traffic to each applications (sub)domain. There is also an automatic system at work that fetches Let's Encrypt certificates to secure each individual app. While the external communication is secured, the internal communication from the proxy to the containers runs unencrypted.

In its default state, Laravel is not configured to run behind such a proxy setup. Normally it assumes, that the request reaching it uses the right protocol. Secured or unsecured. Based on this, all links are going to be generated.

The communication between the user and the proxy is secured. But the user can't reach the application directly with a request and hit Laravels endpoints. As a result some problems can occur.

But we can tweak Laravel and the nginx instance on which it runs to work within this scenario.

First we need to tell Laravel, that when its in production mode it should always behave as when a secured requests hits its endpoints. We can do this in the boot method of the AppServiceProvider.

/* app/Providers/AppServiceProvider.php */

public function boot() : void
{
    // Always use https for urls in production
    if (App::environment('production'))
    {
        URL::forceScheme('https');
    }
}

The second part concernes the TrustProxy middleware. We need to trust our proxy. The easiest way is to trust all proxies. Although the proxy and container communicate unsecured, this should not be a problem, because our container can't be reached from outside without the proxy.

/* app/Http/Middleware/TrustProxies.php */

protected proxies = '*'

If your app, like mine, uses Laravel Livewire there is one final step necessary. If you get a 401 Unauthorized, you'll need to add a special location to your nginx configuration.

location ^~ /livewire {
    try_files $uri $uri/ /index.php?$query_string;
}

After this three steps, your app should run fine behind a nginx reverse proxy.