Development

Laravel + Filament + Private Disk on Cloudways

Introduction

After a long, frustrating debugging exercise, I have discovered a quick tip for my Cloudways + Laravel friends. The “why” is still a touch fuzzy for me at the moment, but I’ll at least explain the symptoms and the fix.

The goal: Add a private file upload to a Filament resource form, ensuring anonymous users cannot download/view the file.

The issue: Everything was working great in my ddev environment. I could preview and open the files if I was logged in, and I would see a 403 if I was logged out. When I moved this to a Cloudways server I was getting automatically logged-out every time I hit a private file URL. Weird, right?

Code

Here’s the final code (the Cloudways “fix” is further down this page):

Filament resource > Form > Field (app/Filament/Resources/SubmissionResource.php)

 

Private Disk (config/filesystems.php)

 

Route (routes/web.php)

 

Controller (app/Http/Controllers/PrivateFileController.php)

Debugging

My debugging journey for this issue took me down many different paths. It wasn’t pretty. Here are the avenues I explored:

  • File permissions different on the server?
  • Session handling different on the server, or misconfigured?
  • CSRF issues?
  • Caching issues?
  • Issues with how I implemented the FileUpload Filament field?
  • Issues with the downloadSubmission() method in my controller?
  • Route missing necessary middleware? (this was a rabbit hole on this, my first Laravel 11 app)

My debugging lead me to a key realization: it seemed like the issue only presented itself when loading a file preview (in the resource form), or loading the resource (via direct URL). I ended up creating some simple test routes:

Take a look at the return messages; these explain what happens when I hit each of those URLs. I realized, through this testing, that static-file-looking URLs seemed to be triggering the logout. The test.jpg failed but test.test didn’t. A real file (/private-file/submissions/test.png) failed, but /test didn’t. And ALL of these worked fine on my local machine; I didn’t get logged out.

I attempted to use .htaccess to make sure these “static file” urls were handled by index.php, but this didn’t affect things at all. Ultimately I remembered that Cloudways does some nginx handling of static files. I did some digging and discovered I could tell nginx to ignore specific paths. Bingo!

Solution

Tell nginx to exclude /private-file/  urls so Laravel is able to handle them. In the Cloudways control panel you browse to [Your Application] ➙ Application Settings ➙ Varnish Settings and click Add New Exclusion. Add the URL pattern, save the rule, then go back to the General tab and click the Purge button.

Sadly I don’t know why visiting a static-looking nginx-handled URL would cause me to lose the session/authentication. I don’t have time to look into it at the moment (it’s 1:50am) but intend to give it some thought soon. I had to get this all out of my head before retiring for the evening.

Leave a Reply

Your email address will not be published.