Laravel 8 Amazon S3 file upload with example

AWS provides fast asset loading for web application. That's many web application serves images from AWS servers.

In this article, I will share you how you can upload file to Amazon S3 using Laravel application. We will go step by step in AWS console.

Step 1: Create S3 bucket

In the first step, we will create s3 bucket. First login to Amazon web console and login to console. In the Service Lists, select S3 option. When you click Create Bucket button, it will ask few details about bucket.

Now create I AM User and click Add Users button

Next add user name and select "Programmatic access" from access type. Then click on next.

Now select “Attach Existing Policy Directly” and choose "AmazonS3FullAccess" from permission link.

Though you can skip and click to next as it is optional.

Now view user details and then click on "Create User" button to create a new user.

You will see created user in link. You can find the "Access Key ID" and "Secret Access Key" that we will use it in .env file.

Step 2: Create Laravel application

Now we need to create fresh Laravel application using following command. We are going from scratch, So open your Terminal or CMD and run below command:

composer create-project laravel/laravel aws

Step 3: Install Amazon S3 Composer package

Now run the following command to install Amazon S3 package using composer command.

composer require --with-all-dependencies league/flysystem-aws-s3-v3 "^1.0"

Step 4: Add AWS S3 Credentials

Now in your project root directory, add AWS credentials in your .env file as like below:


Step 5: Create routes

In this step, we will generate new two routes in web.php file. One route for generate form and another for post method So let's create both route as below.

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ImageController;

Route::get('image-upload', [ImageController::class, 'index' ])->name('image.index');
Route::post('image-upload', [ImageController::class, 'upload' ])->name('image.upload');

Step 6: Create ImageController

In this step, we will create ImageController and write two method index() and upload(). So one method will handle get method another one for post. So create a ImageController using command.

php artisan make:controller ImageController

Add two methods in it.

namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ImageController extends Controller
     * Display a listing of the resource.
     * @return \Illuminate\Http\View
    public function index()
        return view('index');
     * handle upload file
     * @return \Illuminate\Http\Response
    public function post(Request $request)
            'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
        $image_name = time().'.'.$request->image->extension();  
        $path = Storage::disk('s3')->put('images', $request->image);
        $path = Storage::disk('s3')->url($path);

        // here you need to store image path in database
        return redirect()->back()
            ->with('success', 'Image uploaded successfully.')
            ->with('image', $path); 

Step 7: Create Blade view

In this step, we will create a blade file for upload view. Create index.blade.php file at resources/views folder.

<!DOCTYPE html>
    <title>File upload</title>
    <link href="[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
        <div class="container">
            <div class="panel panel-primary">
              <div class="panel-heading"><h2>File upload/h2></div>
              <div class="panel-body">
                @if ($message = Session::get('success'))
                <div class="alert alert-success alert-block">
                    <button type="button" class="close" data-dismiss="alert">×</button>
                        <strong>{{ $message }}</strong>
                <img src="{{ Session::get('image') }}">
                @if (count($errors) > 0)
                    <div class="alert alert-danger">
                        <strong>Whoops!</strong> There were some problems with your input.
                            @foreach ($errors->all() as $error)
                                <li>{{ $error }}</li>
                <form action="{{ route('image.upload') }}" method="post" enctype="multipart/form-data">
                    <div class="row">
                        <div class="col-md-6">
                            <input type="file" name="image" class="form-control">
                        <div class="col-md-6">
                            <button type="submit" class="btn btn-success">Upload</button>

Now hit the artisan command to run server.

php artisan serve

In your browser go to the http://localhost:8000/image-upload page and upload file.