Cloud Services

How to upload files to Amazon s3 using Laravel

When maintaining a Laravel application, sometimes we need to store user files like images, pdf’s, videos, etc., and the first idea that comes up is to save everything on the server. That is not a problem; in fact, it is the most common way of doing it, but at some point, our application will require the storage of a more significant number of files or massive files. Fortunately, AWS provides a dedicated service to upload files to Amazon S3 easily and quickly.

What is AWS S3?

AWS S3 is a mass storage service, virtually unlimited with really impressive advantages. We will never have to worry about adding more storage volumes to our infrastructure because Amazon’s scalability will be responsible for providing as many storage volumes as required, which will be transparently and practically imperceptible for the end-user as well as for us.

Amazon S3 Storage has a lot of good reasons to opt for its use, but this time we will focus on 3:

  • 99.9% availability.
  • A permission system to access the files is completely configurable in our AWS console.
  • Allows storing files between 0 bytes and 5 gigabytes.

How to Integrate AWS S3 with Laravel?

Nowadays, Laravel provides an easy way to upload files to Amazon s3. The process to do it is really simple because Laravel has, by default, the configuration to use it when you want. In order to integrate it successfully, we only require our AWS credentials to access the console to create a new S3 bucket. Easy right?
Next, we will create a small application to join all these concepts and see them in action.

ALSO READ:Laravel 5.6 vs Symfony 4: The Best PHP Framework Battle

Steps to Upload Files to Amazon S3 using Laravel

1. Create a clean installation of Laravel; in your terminal, you can run this command:

laravel new laravel_s3 or composer create-project --prefer-dist laravel/laravel laravel_s3

2. Go to this link to set up an S3 bucket:
2.1 Click on Create Bucket and enter a name (names of the buckets are shared among the entire Amazon S3 network, so if we create a bucket, nobody else can use that name for a new bucket).

3. Now we need to create a bucket policy, so we need to go to this link. To generate a proper policy you need to get the following image and select DeleteObject, GetObject, and PutObject as actions.s3 or composer create-project –prefer-dist laravel/laravel laravel_s3

3.1. Click the Add Statement button and then Generate Policy.

  1. {
  2. “Id”: “PolicyXXXXXXXXXXX”,
  3. “Version”: “XXXXXXX”,
  4. “Statement”: [
  5. {
  6. “Sid”: “StmtXXXXXXXXXX”,
  7. “Action”: [
  8. “s3:DeleteObject”,
  9. “s3:GetObject”,
  10. “s3:PutObject”
  11. ],
  12. “Effect”: “Allow”,
  13. “Resource”: “arn:aws:s3:::laravels3demo/images”,
  14. “Principal”: “*”
  15. }
  16. ]
  17. }

This json result will be put in the Bucket Policy tab located here.

4. Now we will go here to get our Access Key Id and Secret Access Key to put them on our .env file

5. In our Laravel project, we need to go to the terminal and execute the next command to install the S3 package:

composer require league/flysystem-aws-s3-v3

6. Let’s update the Laravel code

Note:
If you are using a Laravel version >= 5.5 the AWS configuration should be register automatically otherwise you need to follow the next steps:

1. Open the config/app.php file.
2. Add Aws\Laravel\AwsServiceProvider::class to 'providers' array.
3. Add 'AWS' => Aws\Laravel\AwsFacade::class, to 'aliases' array.
4. Run in your terminal  php artisan vendor:publish --provider="Aws\Laravel\AwsServiceProvider"

TO CONSIDER:

As a best practice you should set up your AWS credentials in the .env file to avoid hardcode the config/aws.php., this will keep secure your confidential information.

6.1 routes/web.php

<?php
Route::get('/', 'WelcomeController@index');
Route::resource('images', 'WelcomeController', ['only' => ['store', 'destroy']]);

6.2 Create a new controller and update with this code

php artisan make:controller WelcomeController
 
<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
 
class WelcomeController extends Controller
{
public function index()
{
$url = 'https://s3.' . env('AWS_DEFAULT_REGION') . '.amazonaws.com/' . env('AWS_BUCKET') . '/';
$images = [];
$files = Storage::disk('s3')->files('images');
foreach ($files as $file) {
$images[] = [
'name' => str_replace('images/', '', $file),
'src' => $url . $file
];
}

return view('welcome', compact('images'));
}
 
public function store(Request $request)
{
$this->validate($request, [
'image' => 'required|image|max:2048'
]);
 
if ($request->hasFile('image')) {
$file = $request->file('image');
$name = time() . $file->getClientOriginalName();
$filePath = 'images/' . $name;
Storage::disk('s3')->put($filePath, file_get_contents($file));
}
 
return back()->withSuccess('Image uploaded successfully');
}
 
public function destroy($image)
{
Storage::disk('s3')->delete('images/' . $image);
 
return back()->withSuccess('Image was deleted successfully');
}
}

6.3 And finally will update our welcome.blade.php view

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel S3</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
<style>
body, .card{
background: #ededed;
}
</style>
</head>
<body>
<div class="container">
<div class="row pt-5">
<div class="col-sm-12">
@if ($errors->any())
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert">×</button>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if (Session::has('success'))
<div class="alert alert-info">
<button type="button" class="close" data-dismiss="alert">×</button>
<p>{{ Session::get('success') }}</p>
</div>
@endif
</div>
<div class="col-sm-8">
@if (count($images) > 0)
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
@foreach ($images as $image)
<div class="carousel-item {{ $loop->first ? 'active' : '' }}">
<img class="d-block w-100" src="{{ $image['src'] }}" alt="First slide">
<div class="carousel-caption">
<form action="{{ url('images/' . $image['name']) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-default">Remove</button>
</form>
</div>
</div>
@endforeach
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
@else
<p>Nothing found</p>
@endif
</div>
<div class="col-sm-4">
<div class="card border-0 text-center">
<form action="{{ url('/images') }}" method="POST" enctype="multipart/form-data" class="form-horizontal">
{{ csrf_field() }}
<div class="form-group">
<input type="file" name="image" id="image">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Upload</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
</body>
</html>

7. That’s it, you’ve uploaded files to s3 using Laravel.
Note: You can use Laravel Forge to create highly scalable applications on AWS.

Upload files to s3 using Laravel is really easy and useful, on the one hand, we have all Amazon’s capacity and scalability, and on the other, the solidity and practicality offered by Laravel, the combination of these two elements give us the possibility of taking our applications so far as we can imagine. This kind of tactics will help you to increase the performance and scalability of PHP applications, and relying on AWS to make it is the key for successful projects.

As a best practice you should set up your AWS credentials in the `.env` file to avoid hardcode the `config/aws.php`, this will keep secure your confidential information.

Common Question about Upload Files to Amazon s3 Using Laravel

What is Amazon S3, and why should I use it with Laravel?

Amazon S3 (Simple Storage Service) is a scalable cloud storage service provided by AWS. It allows you to store and retrieve any amount of data. S3 with Laravel offers seamless integration through Laravel’s built-in filesystem abstraction, making it easy to manage file uploads, recover files, and organize them.

Can I store files in private folders on S3 using Laravel?

Yes, you can store files in private folders on Amazon S3 using Laravel. Configuring the appropriate permissions and access control policies ensures that the files stored within specific folders are private and only accessible to authenticated users.

How can I track the progress of file uploads in Laravel?

Laravel doesn’t natively support tracking file upload progress out of the box, but you can implement this functionality using JavaScript and AJAX.

Published by
DevOps Guy

Recent Posts

Benefits of Migrating to AWS Mexico Region

AWS launched a data center in Mexico. This new region, based in Querétaro with three…

15 hours ago

Best Remote AI Companies to Work For In 2025

Most job seekers I talked to recently are searching for the best remote AI companies…

2 days ago

Best Data Analytics Tools by Industry: Top Picks for 2025

In 2025, organizations are making smarter business decisions that drive true revenue. And it’s all…

1 week ago

The Best 10 GenAI Tools for CTOs in 2025

GenAI tools are revolutionizing the tech landscape, enabling CTOs to enhance software development, security, observability,…

2 weeks ago

AWS Mexico Data Center Launch: A New Era for Cloud Growth

AWS has officially launched its new Data Center in Querétaro, Mexico​. This AWS Mexico data…

2 weeks ago

AWS Migration to IaC & Well-Architected Framework Implementation

One of our recent collaborations was with a recording studio company in London, where we…

3 weeks ago