storing files to aws s3 using laravel
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Storing Files to AWS S3 with Laravel: A Deep Dive into the Filesystem Abstraction
As a senior developer, I often encounter scenarios where developers want to leverage cloud storage solutions like Amazon S3 for application assets rather than relying solely on local disk storage. Laravel provides an incredibly elegant and powerful abstraction layer for this, primarily through its Filesystem component. This guide will walk you through exactly how to store files to AWS S3 within a Laravel application, specifically addressing the confusion around the Storage::put() method when using custom disk configurations.
Understanding Laravel's Filesystem Abstraction
Laravel’s filesystem abstraction is one of its most powerful features. It decouples your application code from the underlying storage mechanism—whether that’s the local disk, Amazon S3, or an FTP server. This decoupling means you write generic file operations, and Laravel handles the specific API calls required by the chosen driver.
The configuration for this system resides in config/filesystems.php. As you correctly observed, this file defines various "disks" that your application can interact with. Your setup correctly defines an s3 disk:
// config/filesystems.php excerpt
'disks' => [
// ... other disks
's3' => [
'driver' => 's3',
'key' => '*********',
'secret' => '******',
'region' => 'my region',
'bucket' => 'bucketname',
],
],
This configuration tells Laravel how to connect to S3. Now, we need to know how to tell the Storage facade which disk to use when performing an operation like saving a file.
Resolving the Mystery of Storage::put()
The confusion often arises because the methods on the Storage facade (like put, putFile, move) are context-aware. They don't inherently know which configured disk you want to target unless you explicitly tell them.
When you call a method like Storage::put('file.jpg', $contents);, Laravel looks for a default configuration or requires explicit scoping if multiple disks exist. The key to specifying the destination is by using the disk() method to select the desired driver before executing the operation.
Practical Example: Storing Files to S3
To successfully store a file on your configured S3 disk, you must first specify that you intend to operate within the s3 context.
Here is the correct and robust way to use the filesystem abstraction to upload a file to S3:
use Illuminate\Support\Facades\Storage;
class FileUploader
{
public function uploadFile(string $filename, string $contents)
{
// 1. Specify the disk you want to use (the 's3' disk defined in filesystems.php)
$disk = Storage::disk('s3');
// 2. Use the disk instance to perform the storage operation
// The method call will now target the S3 configuration.
$disk->put($filename, $contents);
return true;
}
}
// Example usage:
$uploader = new FileUploader();
$fileContents = file_get_contents('path/to/your/local/file.jpg'); // Assume you have the content ready
$uploader->uploadFile('images/profile.jpg', $fileContents);
echo "File successfully stored on S3!";
Alternative: Using Facade Chaining
While the method above is explicit, Laravel often allows for cleaner syntax by chaining methods directly off the facade when using specific disk wrappers. For instance, if you are working with a file path, you can chain it immediately:
// Storing content directly to S3 without explicitly calling $disk->put()
Storage::disk('s3')->put('images/profile.jpg', $contents);
This chained approach is often preferred for brevity in controller logic, making your business logic cleaner while still ensuring the operation targets the correct cloud storage endpoint defined by your configuration. This level of abstraction is precisely what makes frameworks like Laravel so developer-friendly and powerful when dealing with complex external services like AWS S3.
Conclusion
By understanding the concept of "disks" in config/filesystems.php and utilizing the Storage::disk('s3') method, you gain complete control over where your application stores data. This approach ensures that your file operations are consistent, testable, and easily switchable between local development storage and scalable cloud solutions like AWS S3. Embrace this abstraction to build highly decoupled and maintainable applications.