‹ All Posts

Using S3 with Laravel in 2020

Recently I needed the ability to expand the service of a standard Laravel app to include functions like allowing users to upload documents and images. While a common strategy is to store files in your Laravel storage/ directory, today I'll show you how to swap out your disk storage for Amazon S3, offering the ability to scale your storage infrastructure dynamically.


So what's Amazon S3?

Amazon S3 is an easy-to-use data storage service provided by AWS. While the AWS console can traditionally be intimidating, the S3 team has gone a long way to make the S3 dashboard easier to use over the last few months. Unfortunately, the drawback to these updates results in a different user interface than most Laravel S3 tutorials showcase today.


Getting Started

So you're intrigued? Awesome, let's get started.


To begin, you need to have already covered a few bases:

Prerequisite: Install the Flysystem S3 Driver

Unfortunately, while close, Laravel doesn't completely work with Amazon S3 out-of-the-box. To get started using S3 with Laravel, run the following command to install the S3 driver:


composer require league/flysystem-aws-s3-v3


Alternatively, you can also add league/flysystem-aws-s3-v3 to your composer.json file and update your packages using composer update.

Getting an AWS access token

To allow Laravel to act on your behalf, or optionally an IAM user, you'll first need to generate an access token that we'll store in your project's .env file.


To generate an access key for your root account, visit the Security Credentials page in the AWS Management Console. For IAM users, (which can offer better security), you can get credentials from the IAM console by visiting your IAM user's overview page and visiting the "Security Credentials" tab.


Security Credentials for a Root user account

Security Credentials for an IAM user account


Configuring Laravel to use AWS

After generating a new Access Key, you'll insert the key's ID and Secret into your .env file:


...

AWS_ACCESS_KEY_ID="<YOUR KEY ID>"
AWS_SECRET_ACCESS_KEY="<YOUR KEY SECRET>"


Awesome, you've now configured your Laravel instance with the proper credentials to communicate with AWS! Now let's get to work connecting to S3.


Creating an Amazon S3 "Bucket"

But wait, what's a "bucket"?

A "bucket" in Amazon S3 is where you'll store your files. Think of it as your file disk in the cloud.


To get started with Amazon S3, log back into your AWS console and search for S3 under Services, or select it from the Services List below the search bar.


Once on the S3 Dashboard, select Create Bucket at the top right of the page.



On the next page, fill out your Bucket Details



If you're not experienced with S3 make sure to leave the privacy settings of your Bucket to Block all public access by default. (Don't worry, you can selectively allow files to be public using the ->setVisibility() method in Laravel).


Configuring Laravel to use S3

After creating your S3 bucket, we'll head back over your .env file and insert the following values:


...

AWS_DEFAULT_REGION="<YOUR BUCKET REGION>"
AWS_BUCKET="<YOUR BUCKET ID>"


If you're utilizing IAM Permission Management

You can configure your S3 Policies to only allow the following permissions:

  • s3:GetObject
  • s3:PutObject
  • s3:ListBucket
  • s3:DeleteObject
  • s3:PutObjectAcl
  • s3:GetObjectAcl

You can also find an example IAM JSON Policy here.


Right on! We're almost there. Now that Laravel is configured to use S3, we can learn how to interact with objects, or files, from your application.


Interacting with S3

Here are a few examples of how to interact with the S3 Storage driver, allowing you to perform many common functions on files:

Storing Files

use Illuminate\Support\Facades\Storage;

$contents = $request->get('avatar');

return Storage::put('file.jpg', $contents);


Retrieving Files

$contents = Storage::get('file.jpg');


Downloading Files

return Storage::download('file.jpg');


Setting File Visibility

$visibility = Storage::getVisibility('file.jpg');

Storage::setVisibility('file.jpg', 'public');


Credit for most of these examples belongs to the Laravel docs where you can check out just how much more you can do with S3!


Well, that should be it! If you have any questions feel free to reach out, I'd love to help. 👋




2020 © Bryson Reece