Laravel Amazon S3 File Upload Tutorial

Share this post on:
Laravel , AMZON S3 file Upload Tutorial

Amazon S3 is a reliable and scalable object storage service offered by AWS. In this tutorial, we’ll walk through how to upload files to Amazon S3 in a Laravel application—from setting up your AWS credentials to handling file uploads using Laravel’s built-in storage system.

Step 1: Create an S3 Bucket and IAM User

1.1 Create an S3 Bucket

  1. Log in to your AWS Console.
  2. Navigate to S3 from the list of services.
  3. Click Create Bucket.
AWS S3 Console: Create bucket form showing fields to enter bucket name and region.
  • Enter a unique bucket name and select a region.
  • Leave default settings unless specific access settings are needed.
  • Click Create Bucket to finish.

1.2 Create IAM User with S3 Access

  1. Navigate to the IAM Console.
  2. Click Users > Add User.
Laravel Blade upload form UI in browser: file input field and ‘Upload’ button.
  1. Enter a username (e.g., laravel-uploader).
  2. Choose Programmatic access as the access type.
  3. Click Next: Permissions.
  4. Select Attach existing policies directly and choose AmazonS3FullAccess.
AWS IAM user creation screen: 'Attach existing policies directly' with AmazonS3FullAccess policy selected
  1. Skip the remaining steps or add tags as needed.
  2. Click Create User.
  3. Copy and save the Access Key ID and Secret Access Key—you’ll need these for Laravel.
Laravel upload page showing success message and uploaded image displayed via S3 URL


Step 2: Install Laravel

composer create-project --prefer-dist laravel/laravel s3-blog

Step 3: Install Amazon S3 Composer Package

If you have not installed amazon s3 package, then you have to install s3 composer package by using following command:

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

Step 4: Configure AWS Credentials in Laravel

Open your .env file and add the following:

FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=your_aws_access_key AWS_SECRET_ACCESS_KEY=your_aws_secret_key
AWS_DEFAULT_REGION=us-east-2
AWS_BUCKET=your_bucket_name
AWS_USE_PATH_STYLE_ENDPOINT=false

Then, ensure your config/filesystems.php includes the correct S3 configuration:

's3' => [
         'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'),
         'secret' => env('AWS_SECRET_ACCESS_KEY'),
         'region' => env('AWS_DEFAULT_REGION'),
        'bucket' => env('AWS_BUCKET'),
        'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
],

Step 5: Create Routes

Update your routes/web.php to include upload routes:

use App\Http\Controllers\ImageUploadController;

Route::get('image-upload', [ImageUploadController::class, 'imageUpload'])->name('image.upload');

Route::post('image-upload', [ImageUploadController::class, 'imageUploadPost'])->name('image.upload.post');

Step 6: Create Controller

php artisan make:controller ImageUploadController

Then update app/Http/Controllers/ImageUploadController.php:

namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
 
class ImageUploadController extends Controller
{
    public function imageUpload()
    {
        return view('imageUpload');
    }
 
    public function imageUpl oadPost(Request $request)
    {
        $request->validate([
            'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);
        $path = Storage::disk('s3')->put('images', $request->file('image'));
        $url = Storage::disk('s3')->url($path);
 
        return back()
            ->with('success', 'Image uploaded successfully.')
            ->with('image', $url);
    }
}

Step 7: Create Blade View

Create a Blade view at resources/views/imageUpload.blade.php:

<!DOCTYPE html>

<html>

<head>

    <title>Laravel S3 Image Upload</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">

</head>

<body>

<div class="container mt-5">

    <div class="card">

        <div class="card-header">

            <h3>Upload Image to Amazon S3</h3>

        </div>

        <div class="card-body">

            @if (session('success'))

                <div class="alert alert-success">{{ session('success') }}</div>

                <img src="{{ session('image') }}" class="img-fluid mt-2" />

            @endif

            @if ($errors->any())

                <div class="alert alert-danger">

                    <strong>Oops!</strong> There were some issues with your input:

                    <ul>

                        @foreach ($errors->all() as $error)

                            <li>{{ $error }}</li>

                        @endforeach

                    </ul>

                </div>

            @endif

            <form action="{{ route('image.upload.post') }}" method="POST" enctype="multipart/form-data">

                @csrf

                <div class="form-group">

                    <label>Select Image</label>

                    <input type="file" name="image" class="form-control" required>

                </div>

                <button type="submit" class="btn btn-success mt-2">Upload</button>

            </form>

        </div>

    </div>

</div>

</body>

</html>

Step 8: Run and Test

Run your Laravel server:

php artisan serve

Open your browser and visit:

http://localhost:8000/image-upload

Try uploading an image—if successful, the image will be stored in S3 and a preview will be displayed.

Make S3 Files Public:

To make your uploaded images publicly accessible, go to your S3 bucket > Permissions > Bucket Policy, and add:

{
	"Version": "2012-10-17",
	"Statement": [
	{
      	"Sid": "PublicReadGetObject",
      	"Effect": "Allow",
      	"Principal": "*",
      	"Action": "s3:GetObject",
      	"Resource": "arn:aws:s3:::your_bucket_name/images/*"

	} 
	]
}

Replace your_bucket_name with your actual bucket name.

Conclusion

You’ve now successfully integrated Amazon S3 file uploading into your Laravel application. This solution is scalable and secure, making it perfect for image and document management systems.

At 200OK Solutions, we empower teams to build scalable, cloud‑ready applications. Our hands‑on expertise in Laravel and AWS ensures seamless integration with Amazon S3 for reliable file storage and delivery.

Piyush Solanki

PHP Tech Lead & Backend Architect

10+ years experience
UK market specialist
Global brands & SMEs
Full-stack expertise

Core Technologies

PHP 95%
MySQL 90%
WordPress 92%
AWS 88%
  • Backend: PHP, MySQL, CodeIgniter, Laravel
  • CMS: WordPress customization & plugin development
  • APIs: RESTful design, microservices architecture
  • Frontend: React, TypeScript, modern admin panels
  • Cloud: AWS S3, Linux deployments
  • Integrations: Stripe, SMS/OTP gateways
  • Finance: Secure payment systems & compliance
  • Hospitality: Booking & reservation systems
  • Retail: E-commerce platforms & inventory
  • Consulting: Custom business solutions
  • Food Services: Delivery & ordering systems
  • Modernizing legacy systems for scalability
  • Building secure, high-performance products
  • Mobile-first API development
  • Agile collaboration with cross-functional teams
  • Focus on operational efficiency & innovation

Piyush is a seasoned PHP Tech Lead with 10+ years of experience architecting and delivering scalable web and mobile backend solutions for global brands and fast-growing SMEs.

He specializes in PHP, MySQL, CodeIgniter, WordPress, and custom API development, helping businesses modernize legacy systems and launch secure, high-performance digital products.

He collaborates closely with mobile teams building Android & iOS apps, developing RESTful APIs, cloud integrations, and secure payment systems. With extensive experience in the UK market and across multiple sectors, Piyush is passionate about helping SMEs scale technology teams and accelerate innovation through backend excellence.