When deploying a Laravel application that utilizes Filament PHP as an admin panel and Laravel Vapor for serverless deployment, you might encounter an issue where uploaded images appear broken on the frontend. This post will walk you through understanding why this happens and how to fix it.
The Issue
After successfully uploading an image through the Filament admin panel, the image is stored in Amazon S3, and its path is saved in the database. However, when you try to display this image on your frontend, it shows up as a broken link.
This issue specifically arises when using Laravel Vapor with Filament PHP because of how file storage disks are configured in a serverless environment.
Understanding the Cause
By default, Filament uses the filesystem disk specified in your config/filament.php
file, typically something like:
'default_filesystem_disk' => env('FILESYSTEM_DISK', 'public'),
In a local or traditional server environment, this works fine because the public
disk is accessible. However, when deploying with Laravel Vapor, the filesystem behaves differently due to the serverless nature of the platform.
Vapor uses S3 for file storage, and the local filesystem is not persistent between requests. Therefore, any references to the local public
disk won't work as expected in Vapor.
The Solution
To resolve this issue, we need to tell our application to use the s3
disk when running in the Vapor environment. Laravel Vapor sets specific environment variables that we can use to detect if the application is running on Vapor.
One such environment variable is VAPOR_ARTIFACT_NAME
. According to the Vapor documentation, this variable is only set when the application is running in Vapor.
Updating the Configuration
We can modify the default_filesystem_disk
configuration in config/filament.php
to conditionally use the s3
disk when on Vapor:
'default_filesystem_disk' => isset($_ENV['VAPOR_ARTIFACT_NAME']) ? 's3' : env('FILESYSTEM_DISK', 'public'),
However, checking for the VAPOR_ARTIFACT_NAME
ensures that this configuration only applies when running on Vapor, which is more precise if you have multiple production environments.
Displaying the Image on the Frontend
After resolving the broken image issue by configuring the default_filesystem_disk
, you can display images on your frontend by dynamically referencing the uploaded image from Amazon S3. Add the following code snippest where you wanted to display the image.
{{ Storage::url($your_variable_name) }}
Complete Steps
- Open your
config/filament.php
file. - Locate the
default_filesystem_disk
configuration key. - Modify it to include the Vapor environment check:
- Ensure your
filesystems.php
configuration has thes3
disk properly configured. - Add the storage URL where ever you wanted to display the image:
Storage::url($your_variable_name)
- Deploy your application to Vapor again.
'default_filesystem_disk' => isset($_ENV['VAPOR_ARTIFACT_NAME']) ? 's3' : env('FILESYSTEM_DISK', 'public'),
Verifying the Fix
After deploying the updated configuration:
- Upload a new image through the Filament admin panel.
- Navigate to the frontend where the image should be displayed.
- The image should now load correctly, indicating that it's being served from S3.
Additional Considerations
- Caching Configurations: Remember to clear your configuration cache if you're testing locally:
php artisan config:clear
Reference
Vapor Environment Variables: Laravel Vapor Documentation
Conclusion
By adjusting the filesystem disk configuration based on the environment, you can ensure that your Laravel application works seamlessly both locally and when deployed to Laravel Vapor. This approach helps in maintaining a consistent behavior across different environments and resolves the issue of broken images when using Filament PHP with Vapor.
Feel free to share your thoughts or ask questions in the comments below!