Using Digital Ocean Spaces as Strapi Storage
Tags: nextjs, react, node, javascript
Published: 2024-05-16 11:50:03

To read more articles like this, [visit my blog](https://www.mdfaisal.com/blog)


So recently, I migrated a website from WordPress to Strapi + NextJS.

The client didn’t want Strapi’s own cloud service and wanted to stick to Digital Ocean as he already knows that well.

So, I set up Strapi on Digital Ocean using their [app service](https://docs.strapi.io/dev-docs/deployment/digitalocean-app-platform), which is, I would say, not " beginner-friendly” but should be easy enough for someone technical.

## The problem

So after I uploaded a couple of content with images. They worked pretty well.

But as soon as I added a new field to a new collection or do anything that triggers a new build the images were gone.

## The Issue

The problem was that strapi, by default, uses a local upload provider. A local provider means the images are stored on the machine.

Every time you build — the machine restarts, and the images are gone.

## Solution

The solution is to use persistent storage. In fact, Strapi provides several options.

[**Upload | Strapi Documentation**](https://docs.strapi.io/dev-docs/plugins/upload#using-a-provider)

Now, here is another problem. Strapi’s official documentation supports

* [Amazon S3](https://market.strapi.io/providers/@strapi-provider-upload-aws-s3)

* [Cloudinary](https://market.strapi.io/providers/@strapi-provider-upload-cloudinary)

But my client wanted to stick to Digital Ocean. So what to do?

## Comes the Digital ocean spaces

Digital Ocean Spaces is actually an S3-compatible storage provider, which means it only provides a wrapper on top of the S3.

To use this, First, create a digital ocean space using the following guide
[**How to Create a Spaces Bucket | DigitalOcean Documentation**](https://docs.digitalocean.com/products/spaces/how-to/create/)

Then, get the access key and the secret access key using this guide.
[**How to Manage Administrative Access to Spaces | DigitalOcean Documentation**](https://docs.digitalocean.com/products/spaces/how-to/manage-access/#access-keys)

## Install AWS provider

Now, go to the Strapi application and install [s3 provider](https://www.npmjs.com/package/@strapi/provider-upload-aws-s3)

```
npm i @strapi/provider-upload-aws-s3
```

Then open up your plugins.ts file and add the following code.

```
export default ({ env }) => ({
  // ... other configs,
  upload: {
    config: {
  provider: "aws-s3",
      providerOptions: {
        credentials: {
          accessKeyId: env("DO_SPACE_ACCESS_KEY"),
          secretAccessKey: env("DO_SPACE_SECRET_KEY"),
        },
        region: env("DO_SPACE_REGION"),
        endpoint: env("DO_SPACE_ENDPOINT"),
        params: {
          Bucket: env("DO_SPACE_BUCKET"),
        },
      },
      actionOptions: {
        upload: {},
        uploadStream: {},
        delete: {},
      },
    },
  },
});
```

Then, add the following values to the `.env` file.

```
DO_SPACE_ACCESS_KEY=___
DO_SPACE_SECRET_KEY=___
DO_SPACE_ENDPOINT=https://fra1.digitaloceanspaces.com
DO_SPACE_BUCKET=YOUR_BUCKET_NAME
DO_SPACE_REGION=REGION_NAME (in this case fra1)
```

Notice several things.

The space endpoint can’t have the bucket name at the beginning. This is a very common mistake that is not mentioned in the docs.

So if your Origin Endpoint looks like this

```
https://any-bucket-name.fra1.digitaloceanspaces.com
```

Your `DO_SPACE_ENDPOINT value should be`

```
https://fra1.digitaloceanspaces.com
```

And obviously, the region will be `fra1`

## Modify Middleware

You are not done yet. Although this will work, when you visit the CMS, you will see that the previews are not loading.

![](https://cdn-images-1.medium.com/max/4948/1*z1oWI_fdEameTPi9Ihvoqg.png)

To fix this, we have to allow Strapi access to the S3 bucket.

**Let’s do that…**

Now open the `middlewares.ts` file and add the following

```
export default [  
// ...others 
{
    name: "strapi::security",
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          "connect-src": ["'self'", "https:"],
          "img-src": [
            "'self'",
            "data:",
            "blob:",
            "strapi.io",
            "{BUCKET_NAME}.s3.{REGION}.amazonaws.com",
            "https://{BUCKET_NAME}.s3.{REGION}.amazonaws.com"
          ],
          "media-src": [
            "'self'",
            "data:",
            "blob:",
            "strapi.io",
            "{BUCKET_NAME}.s3.{REGION}.amazonaws.com",
            "https://{BUCKET_NAME}.s3.{REGION}.amazonaws.com"
          ],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
];
```

### Notice a few things

Replace the BUCKET_NAME and the REGION values in the `middlewares.ts`.

Then restart your Strapi server, and you should be able to upload images to the digital ocean spaces.

This configuration should fix the issues, and you will see the previews.

![Previews.](https://cdn-images-1.medium.com/max/4916/1*sRd3bzgZTcr0lTM5Su0rPA.png)

Upload an image and check the spaces to verify that it’s working. Also, don’t forget to add the `.env` variables to your digital ocean dashboard.

Thank you for reading this far! Have a great day!

**Have something to say? Get in touch with me via [LinkedIn](https://www.linkedin.com/in/56faisal/) or [Personal Website](https://www.mdfaisal.com/)**