Store files on Digital Ocean Spaces with Laravel

Digital Ocean Spaces

All of my Laravel projects are hosted on Digital Ocean thanks to Laravel Forge. When it comes to storing files on the cloud, I used to work with either Dropbox or Amazon S3.

Dropbox was fine because I knew the product and the interface was easy to use but I experienced a lot of outages and thus avoid it for important files now.

Amazon S3 was fine because it was cheap, but the user interface is… well… it’s cheap..

But recently Digital Ocean announced their new product called “Spaces” that gives the best of the two world: cheap & easy to use. Let’s see how you can start using Digital Ocean Spaces in your Laravel project.

Install & configure

Digital Ocean is S3 compatible. That means we can support it, the same way you’d support Amazon S3.

composer require league/flysystem-aws-s3-v3

This will install the S3 driver into your project. You’ll need to add a new ‘disk’ called ‘spaces’ into your config/filesystems.php

<?php

return [

    ...

    'disks' => [
        ...

        'spaces' => [
            'driver' => 's3',
            'key' => env('DO_SPACES_KEY'),
            'secret' => env('DO_SPACES_SECRET'),
            'endpoint' => env('DO_SPACES_ENDPOINT'),
            'region' => env('DO_SPACES_REGION'),
            'bucket' => env('DO_SPACES_BUCKET'),
        ],
    ],

    ...

Now we need to setup these environment variables. Let’s go to Digital Ocean and create our Space.

Go in the “Spaces” tab of your account and click “Create a Space”.

Select the Region

Select your region, in my case it’s “San Francisco 2”. You can enable the CDN if you want (might be useful if you’ll deliver the files to your users/visitors).

Bucket Name

Choose a unique name, that’s gonna be the “bucket“, in my case I chose “laravelspaces”.

Finish by clicking the “Create a Space” button.

Now we need to create the keys (DO_SPACES_KEY& DO_SPACES_SECRET). For this you’ll need to go to the API tab.

At the bottom of the page you’ll have the “Spaces access keys”. Click “Generate New Key” and give it a name. I chose “journal”.

Access Keys

We have all we need to complete our .env file, it should look like this :

DO_SPACES_KEY=PIAQDUWWZ4QRSCACB7CH
DO_SPACES_SECRET=dmm6AM8ZkHwuqjnhWNbKb13k7IhBSOeNe9MyJPQjyVM
DO_SPACES_ENDPOINT=https://sfo2.digitaloceanspaces.com 
DO_SPACES_REGION=sfo2
DO_SPACES_BUCKET=laravelspaces

Usage

Let’s start using it by uploading some JSON file, for this test I’ll do it in my `/routes/web.php` file.

Route::get('/store', function () {
    $path = config('app.env') . '/' . date('Y-m-d') . '.json'; // local/2019-03-01.json

    Storage::disk('spaces')->put($path, json_encode(['foo' => 'bar']));
});

Now hit your `/store` endpoint and if there all went well you should see the file in your Digital Ocean Spaces interface.

File was uploaded

Now to retrieve this file, we can easily do it like we would any file.

Route::get('/retrieve', function () {
    $path = config('app.env') . '/' . date('Y-m-d') . '.json'; // local/2019-03-01.json

    $file = Storage::disk('spaces')->get($path);

    $result = json_decode($file);

    return response()->json($result);
});

If you hit the `retrieve` endpoint you should see something like this:

File was retrieved

Conclusion

I was a bit confused at the beginning because Digital Ocean doesn’t use the word “bucket”. They use “name” instead.

If you don’t already use Digital Ocean, you can check it out here (referral) and receive a $100 in credit over 60 days.