baspa / laravel-s3-uploader
Upload local files and folders to S3 from an Artisan command
Fund package maintenance!
Requires
- php: ^8.2
- illuminate/console: ^10.0||^11.0||^12.0||^13.0
- illuminate/contracts: ^10.0||^11.0||^12.0||^13.0
- illuminate/filesystem: ^10.0||^11.0||^12.0||^13.0
- illuminate/support: ^10.0||^11.0||^12.0||^13.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- league/flysystem-aws-s3-v3: ^3.0
- nunomaduro/collision: ^8.0
- orchestra/testbench: ^8.0||^9.0||^10.0||^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
Suggests
- league/flysystem-aws-s3-v3: Required to use a real S3 disk (the host application normally provides this)
This package is auto-updated.
Last update: 2026-06-11 10:54:19 UTC
README
Upload a local folder to S3 (or any S3-compatible storage) with a single Artisan command. It reads your existing S3 credentials straight from your application's filesystem configuration, walks a directory recursively, and streams every file to a destination prefix on the bucket.
php artisan s3:upload storage/app/exports backups/2026
Installation
Install the package via composer:
composer require baspa/laravel-s3-uploader
This package uploads through a standard Laravel filesystem disk, so you also need the S3 driver in your application (most Laravel apps already have it):
composer require league/flysystem-aws-s3-v3 "^3.0"
Optionally publish the config file:
php artisan vendor:publish --tag="laravel-s3-uploader-config"
Configuration
The package uploads to a disk defined in your application's config/filesystems.php. By default it uses the s3 disk, which is configured through the usual environment variables:
AWS_ACCESS_KEY_ID=your-key AWS_SECRET_ACCESS_KEY=your-secret AWS_DEFAULT_REGION=eu-central-1 AWS_BUCKET=your-bucket
S3-compatible providers (MinIO, DigitalOcean Spaces, Cloudflare R2, …) work too — just set AWS_ENDPOINT on the s3 disk as you normally would.
Want to point the package at a different disk? Publish the config and change the disk name, or set it in your .env:
S3_UPLOADER_DISK=backups
The published config/s3-uploader.php:
return [ 'disk' => env('S3_UPLOADER_DISK', 's3'), ];
Usage
php artisan s3:upload {source} {destination}
| Argument / option | Description |
|---|---|
source |
The local directory to upload. |
destination |
The destination folder (prefix) on the disk. Use "" to upload to the bucket root. |
--disk= |
Upload to a specific disk instead of the configured default. |
--force |
Overwrite files that already exist on the disk. Without it, existing files are skipped. |
--dry-run |
Show what would be uploaded without writing anything. |
The directory is walked recursively and the folder structure is preserved under the destination prefix. For example, uploading a folder that contains sub/report.pdf to backups/2026 stores it at backups/2026/sub/report.pdf.
Examples
Upload a folder, skipping anything already in the bucket:
php artisan s3:upload storage/app/exports backups/2026
Re-upload everything, overwriting existing objects:
php artisan s3:upload storage/app/exports backups/2026 --force
Preview the upload without touching S3:
php artisan s3:upload storage/app/exports backups/2026 --dry-run
Upload to a different disk:
php artisan s3:upload storage/app/exports backups/2026 --disk=spaces
The command shows a progress bar while uploading and prints a summary afterwards, e.g. Uploaded: 12, Skipped: 3, Failed: 0. It exits with a non-zero status code if any file failed to upload, so it is safe to use in scripts and CI.
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.