Store Laravel uploads off-site in the cloud

Store Laravel uploads off-site in the cloud

·

7 min read

Long time ago uploads folders were common to any larger web project. A folder where uploaded files could be stored and a folder with 777 permission set (Read, Write, Execute on Linux).

For security reasons, having files or folders with write and execute permission is never an optimal solution while working with a website, but also as for risk management such as backup, it’s a better choice to use a storage service. Fortunately this is very easy and cheap to integrate into a Laravel project.

The naming Amazon is used for simplicity here, although the actual name is AWS (Amazon Web Services) which is a subsidiary of Amazon.

Storage Service

Storage services or cloud storage as it is also called dates back to the beginning of the internet in mid-90s, but 10 years later when Amazon introduced their Simple Storage Service (S3) it became a lot easier to benefit from as they provide a simple API and tools to make scaling easy.

Other companies have since started to compete with Amazon. My favourite is DigitalOcean who has adapted the same API as Amazon uses. Whilst not being the only competitor with this feature, I believe DigitalOcean is a great platform for Laravel projects.

Amazon S3

Since DigitalOcean uses the same API as Amazon all the configurations from this article will work for both. You will also realise that the settings in Laravel are referred to as S3. For this reason it’s rather simple to later migrate from DigitalOcean to AWS if you keep the endpoint as a constant in your .env for instance.

Read more about S3 at Amazon: https://aws.amazon.com/s3/

DigitalOcean Spaces

The file storage solution, Spaces, from DigitalOcean works with an API as with Amazon. As mentioned earlier the API is the exact same, although with fewer advanced features.

The advantage of DigitalOcean is that you pay a fixed price per month, starting from $5, while at Amazon prices are fluid based on storage usage, data transfer and so on. It might be cheaper at first using Amazon, but the price changes dynamically for that reason. Larger projects with bigger budgets might have less overhead from Amazon though.

The fixed price includes a range of usage while exceeding this you will be charged, but it’s unlikely that you will exceed.

Read more about DigitalOcean Spaces: https://www.digitalocean.com/products/spaces/

Configure Laravel

Making Laravel ready for a storage service is straight forward and well described in the documentation . I will give a brief description on how to get it running.

Since DigitalOcean utilises the Amazons API, you’ll have to install the AWS SDK in both cases

composer require league/flysystem-aws-s3-v3

Next you need to add a few lines to .env to configure your storage api.

# The secret generated from DigitalOcean API
AWS_ACCESS_KEY_ID=
# Key from DigitalOcean API
AWS_SECRET_ACCESS_KEY=
# Region ID for your Space (nyc2, sgp1, fra1, sfo2, ..)
AWS_DEFAULT_REGION=
# The unique name you chose for your Space
AWS_BUCKET=
# Full URL without name ({REGION}.digitaloceanspaces.com)
AWS_URL=
# Endpoint
AWS_ENDPOINT=digitaloceanspaces.com

You must make one minor change to your filesystem driver in config/filesystem.php by adding the endpoint parameter:

's3' => [
  ...
  'endpoint' => env('AWS_ENDPOINT'),
],

Now you can store files either per default to your cloud storage or when desired also locally.

Cloud as default

If you want to store everything on your cloud, the easiest is to set it as the default storage service in your .env:

FILESYSTEM_DRIVER=s3

Now you can access your cloud storage per default, without declaring a disk:

Storage::..

You can still use the local driver by specifying it:

Storage::disk('local')->..

Cloud as an option

If you rather want to use cloud as an optional feature and not default, you don’t have to do more. Instead you must refer to you the cloud disk when using it:

Storage::disk('cloud')->..

Documentation

For full a full list of features for the Storage class read more in the official documentation: https://laravel.com/docs/7.x/filesystem

Notes

Cross Origin Resource Sharing (CORS)

CORS are probably only relevant to you if you plan to use DigitalOceans CDN feature. In most cases if files are streamed through you application it’s unnecessary to make any changes to these settings.

A few links about CORS https://en.wikipedia.org/wiki/Cross-origin_resource_sharing https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

File listing

You should in most cases disable file listing. It won’t prevent your API and Laravel application to list files on your Space, but it will prevent others from directly typing the URL to your Space and browse the files. File listing can be changed in your Space’s settings:

Screenshot-2019-11-05-at-12.56.32.png

Limits

There are a few limits to the Spaces, but these are unlikely to bother you if you have a small to a medium sized site. If you are facing the limits it’s most likely because you use Space as CDN without configuring it to be so. Read more about limits: https://www.digitalocean.com/docs/spaces/#limits