Amazon Web Services

Cómo subir archivos a Amazon S3 con Laravel

Almacenar archivos en AWS S3 con Laravel

Al mantener una aplicación PHP en Laravel, muchas veces se necesita almacenar archivos de usuario como imágenes, archivos PDF, videos, etc., y la primera idea que surge es guardar todo en el servidor. Eso no es un problema, de hecho, es la forma más común de hacerlo, pero en algún punto, tu aplicación requerirá almacenar una cantidad más grande de archivos o archivos masivos. Afortunadamente, AWS brinda un servicio dedicado para cargar archivos de manera fácil y rápida.

Simple Storage Service, conocido como Amazon S3

AWS S3 es un servicio de almacenamiento masivo, prácticamente ilimitado con ventajas realmente impresionantes. Nunca tendremos que preocuparnos por agregar más volúmenes de almacenamiento a nuestra infraestructura porque la escalabilidad de Amazon será responsable de proporcionar tantos volúmenes de almacenamiento como sea necesario, siendo transparente y prácticamente imperceptible para el usuario final y para ti como desarrollador.

Amazon S3 Storage tiene muchas buenas razones para optar por su uso, pero esta vez nos centraremos en 3:

  • 99,9% de disponibilidad
  • Un sistema de permisos para acceder a los archivos, completamente configurable en tu consola AWS.
  • Permite almacenar archivos entre 0 bytes y 5 gigabytes.

AWS S3 con Laravel, la combinación perfecta.

Hoy en día, Laravel proporciona una manera fácil de integrar Amazon S3. El proceso para hacerlo es realmente simple porque Laravel tiene por defecto la configuración para usar S3 cuando lo desees. Para integrarlo con éxito, solo necesitas tus credenciales AWS para acceder a la consola y crear un nuevo depósito S3. Fácil, ¿verdad?
A continuación, crearás una pequeña aplicación para unir todos estos conceptos y verlos en acción.

Comencemos con el proceso para subir archivos a Amazon S3 con Laravel

1. Crea una instalación limpia de Laravel, en tu terminal puedes ejecutar este comando:

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

2. Ve este link para configurar un bucket en Amazon S3:

2.2 Haz clic en Create bucket e ingresa un nombre (los nombres de los buckets se comparten entre toda la red de Amazon S3, de modo que si creamos uno, nadie más puede usar ese nombre para un bucket nuevo).

3. Ahora tienes que crear una política de bucket, para esto, ve este link Para generar una política adecuada, debes obtener la siguiente imagen y seleccionar DeleteObject, GetObject y PutObject como acciones.

3.2 Haz clic en el botón Add Statement y luego Generate Policy

{
  "Id": "PolicyXXXXXXXXXXX",
  "Version": "XXXXXXX",
  "Statement": [
    {
      "Sid": "StmtXXXXXXXXXX",
      "Action": [
        "s3:DeleteObject",
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::laravels3demo/images",
      "Principal": "*"
    }
  ]
}

Este resultado json se colocará en la pestaña Bucket Policy ubicada Aquí

4. Ahora iremos esta dirección para obtener tu Access Key Id y Secret Access Key para colocarlo en tu .env file

5 En tu proyecto Laravel, tendrás que ir a la terminal y ejecutar el siguiente comando para instalar el paquete S3:

composer require league/flysystem-aws-s3-v3

6. Actualicemos el código de Laravel

6.2 routes/web.php

<?php

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

6.3 Crea un nuevo controlador y actualiza con este código

<!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. Eso es todo, ahora tu proyecto S3 y Laravel están listos para trabajar juntos.

Ahora ya sabes cómo almacenar archivos en Amazon S3 con Laravel

Trabajar con S3 y Laravel es realmente fácil y útil, por un lado, tienes toda la capacidad y escalabilidad de Amazon, y por el otro, la solidez y practicidad que ofrece Laravel, la combinación de estos dos elementos te da la posibilidad de llevar tus aplicaciones hasta el límite.

¡ Déjanos ayudarte con tu nueva aplicación en PHP y Laravel!

Development Clickittech

Share
Published by
Development Clickittech

Recent Posts

Grand Theft Auto V Enhanced Pre-Installed Updated Torrent Download

🛠 Hash code: 665a5d414f7e9fd7dc04a18044908c40Last modification: 2026-06-15VerifyProcessor: 6-core 3.5 GHz minimum required RAM: fast 5600MHz+ required…

4 horas ago

Avowed Cracked Tiny Girl Repack Desktop High-Bitrate .torrent 2026

🔗 SHA sum:61ae7fd3c8ef2fbdf127fed05631f382Updated: 2026-06-14VerifyProcessor: high single-core performance needed RAM: 32 GB highly recommended for Ultra…

8 horas ago

Batch DOC and DOCX Converter Crack + Serial Key

📄 Hash Value:9d0b6209c4f5ef1a2aab73745a03d899📆 Update: 2026-06-19VerifyProcessor: Dual-core CPU for activator RAM: Needed: 4 GB Disk space:…

8 horas ago

Resident Evil 9 Full Unlocked +Day 1 Patch Reddit

🔗 SHA sum:ad0d605c6925e9680141382863d746a4Updated: 2026-06-14VerifyCPU: 8-core / 16-thread recommended RAM: 16 GB or higher for smooth…

12 horas ago

Visual IP Trace Portable only Clean (x32-x64) [100% Worked] Ultimate

🔍 Hash-sum: b8ca16cd73e3a7b46c11a7faa872aa5c🕓 Last update: 2026-06-17VerifyProcessor: Dual-core for keygens RAM: 4 GB for crack use…

16 horas ago

AnyDesk Free[Activated] Windows 10 [Full]

🧩 Hash sum → 25c6b0997b9b9758d0c3da963f48abe6Update date: 2026-06-14VerifyProcessor: Dual-core for keygens RAM: 4 GB for tools…

20 horas ago