Uploading images on AWS S3 from a Laravel 4 application

Laravel

Any web application which deals with a lot of images or a lot of file downloads will for sure want to offload their space requirements for images and files from the mail server to buckets like what Amazon provides us. Some may even choose Amazon cloudfront (CDN) for storing images if their traffic is from different geo locations. So, in this tutorial I will show how we can use the Amazon SDK and the Laravel wrapper to store images on Amazon S3 inside a bucket.

Requirements

Laravel version: For this tutorial I will be using Laravel 4.x and not Laravel 5. Although the package that I am using is compatible with Laravel 5, but for simplicity for now let’s stick to Laravel 4 as I have not yet explored the latest version.

Composer package: Also we will be using this package https://github.com/aws/aws-sdk-php-laravel which is also available as a composer package but I had to tweak a few things for it to work with my laravel installation and so I will mention them while installing so that you don’t run into the same problem.

AWS S3 credentials and a bucket: To upload the images on S3, we need to create a bucket on S3 (if you are not on the free trie; don’t worry S3 is dirt cheap and storing GBs of data will hardly cost you anything. And billing is on based on usage and no upfront cost). And for the API to authenticate, you need AWS Access Key ID and AWS Secret Access Key. If you are not sure how to create the following two keys I suggest you go through the AWS docs which explains how to get the two things:

http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html

Installing the package and setting the configuration

Although the github page’s installation mentioned 2.0@beta version will work but for some reason it didn’t work for me on a Laravel 4.X and hence I had to hunt the release stack and went for 1.1.x version. So the require in composer will become “aws/aws-sdk-php-laravel”: “1.1.*”.

Once the package is installed, the config pushed also didn’t work for me and that’s where I lost quite a lot of time. Basically, the config file is not published by default unlike many other packages so we need to copy the config file from vendor/aws/aws-sdk-php-laravel/src/config/config.php and put it inside app/config and name the file as aws.php. Yes the name is also important. Didn’t hunt the main code, but it looks like the code is looking for configurations inside aws.php file. So be it.

Once that is done, rest of the things are normal like adding the service provider and alias in the app.php file so that the class is available to Laravel during bootstrap.

Creating the bucket on S3

Now we need to create a bucket on S3 where we will be uploading the images from the application. The interface for AWS S3 is a simple enough thing; the only which is important in this step is to set the permissions correctly. For my folder the permissions are as shown below:

S3 config

Here, the higher level actions like edit, list is with Me (super user). The “upload and delete” is given to an authenticated user which means an IAM user can upload images and for every one “view permission” is available so that they can check the images.

The upload and delete is given to authenticated user; which means using the AWS Access key and AWS Secret Access key; the app can do actions which is allowed to an authenticated user and hence we would be able to upload and remove images.

The final piece – uploading an image

To keep it simple, for now the entire code is inside a route (yes, I like this approach of first writing the entire code inside one route and once done; distribute the code into models and controllers).

Route::get('s3test', function () {
    
  $s3 = AWS::get('s3');
  $s3->putObject(array(
    'Bucket'     => 'BUCKEYNAMEGOESHERE',
    'Key'        => 'imagename/img.png',
    'SourceFile' => 'img.png',
  ));
});

Here the image img.png is inside the public folder, so any image upload should be relative to the public folder. Once this is done; the image should be visible inside the bucket.

  • The bucket name is the actual bucket name.
  • Key is the final path to where you want to store the file. If you add a folder name; S3 automatically handles that. For me it’s imagename folder and then the image.
  • Source file is the actual file which is going to be uploaded.