Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Nite's avatar
Level 1

Serve file from remote S3 Storage

I'm trying to setup a remote storage using digital ocean (which uses the s3 driver). The idea was to store image files on a protected storage, not accessible for not authenticated users.

Until now we stored the files using the local driver, storing them in the storage folder of the app. Then we served the files to the authenticated users using this :

//Old working code - using local storage
//Note here the default storage in the filesystems config file was set to local
if (!Storage::exists($file_path)) {
	abort('404');
}
return response()->file(storage_path($file_path));

Now, we did setup the filesystems config to use the remote s3 driver as default. But, how to serve the file now ?

//This works, returns the correct remote url
$url = Storage::url($file_path);

//returns true
Storage::exists($file_path)

//Doesnt work (response 500)
return response()->file($url);

//Doesnt work (500)
return Storage::download($url);

What am I missing ?

0 likes
3 replies
martinbean's avatar

@nite It’s really not performant to tie up PHP processes to serve images. If you have a web page that has say, 10 images on it, then that’s going to require 11 PHP threads to render the page, because each image request is going to invoke a HTTP request, boot up the Laravel framework, create database connections, etc.

If you’re storing images as private objects in an S3 bucket then consider using signed URLs. Your application should generate the URLs if the user is authorised to view the requested object, but then the actual serving of the object will still be handled by S3.

1 like
Nite's avatar
Level 1

@martinbean Could you point me into the right direction on how to implement signed urls for this case ?

Nite's avatar
Level 1

@martinbean Also another small problem... currently I work on the app in a local environment, using the app storage (local driver). I know I can setup the default driver in the filesystems config, with the FILESYSTEM_DRIVER variable in the env file.

The problem is that during the last hour googling, I found out that signed urls don't work for the local storage. So I guess I should just use the public driver for dev ? Or is there a way to use the local storage ?

On a final note, in my case I need to load the images urls through the frontend, I guess I have to make a route that provides the signed url for the required image, and then update the image src with js. Is that correct ?

And for image urls directly placed in the blade, I have to generate the signed url in advance.

All the above using Storage::temporaryUrl correct ?

One last note, I also have to stream PDFs stored in the S3 bucket... what to do for those ? I guess response()->file would not work as well.

Thank you

Please or to participate in this conversation.