Upload media to digitalocean spaces using strapi v4

The solution for me ended up being ‘npm cache clear --force’

derp

Im having this exact issue. Follow the advice on the thread and nothing is working. Im using strapi version 4.5.3. Thanks

Hi @panrosk could you describe your problem a little more?

Just got it worked after long debugging.

With:
@strapi/provider-upload-aws-s3”: “^4.5.6”
@strapi/strapi”: “^4.5.6”

Make sure:
plugins.js > plugins.ts.

Make sure:
DO_SPACE_ENDPOINT is without your bucket name, like:
https://ams3.digitaloceanspaces.com

No need to use the digital ocean upload plugin, use the aws one.

1 Like

Hello! I am trying to get Strapi to work with Digital Ocean spaces. I tried following the official documentation as well as tips in this thread but nothing seems to work yet.
When initiating an upload I am getting the following in my strapi server logs:

2023-02-01T16:47:35.610425+00:00 app[web.1]: [2023-02-01 16:47:35.610] e[31merrore[39m: SignatureDoesNotMatch: null

2023-02-01T16:47:35.612535+00:00 heroku[router]: at=info method=POST path="/upload" host=xxx.herokuapp.com request_id=ebdb6c22-9beb-4dc2-ace0-d2da19a0a699 fwd="95.90.238.66" dyno=web.1 connect=0ms service=2342ms status=403 bytes=1033 protocol=https

Also in my client I am getting this at the same time:

code: "ERR_BAD_REQUEST"
config: Object { timeout: 0, xsrfCookieName: "XSRF-TOKEN", xsrfHeaderName: "X-XSRF-TOKEN", … }
message: "Request failed with status code 403"
name: "AxiosError"

I omitted the bucket name from DO_SPACE_ENDPOINT as @Cheston_Go suggests. Any help would be highly appreciated!

Did you create a spaces API key?

Add these:

middlewares.ts
{
name: ‘strapi::security’,
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
‘connect-src’: ["‘self’", ‘https:’],
‘img-src’: ["‘self’", ‘data:’, ‘blob:’, ‘.digitaloceanspaces.com’],
‘media-src’: ["‘self’", ‘data:’, ‘blob:’, '
.digitaloceanspaces.com’],
upgradeInsecureRequests: null
}
}
}
},

plugins.ts
export default ({ env }) => ({
upload: {
config: {
provider: ‘aws-s3’,
providerOptions: {
accessKeyId: env(‘DO_SPACE_ACCESS_KEY’),
secretAccessKey: env(‘DO_SPACE_SECRET_KEY’),
endpoint: env(‘DO_SPACE_ENDPOINT’),
params: {
Bucket: env(‘DO_SPACE_BUCKET’)
}
}
}
}
});

Maybe, not sure if its required.
But go to spaces settings > advanced cors options.
Add an origin: *, with all allowed methods and max age 3000.

Thank you. I was able to make it work by resetting the access key in digital ocean and reassigning it.

Hello
I am trying to get Strapi to work with Digital Ocean Spaces.
I tried every solution I found in this thread and others. I am using Strapi version 4.5.6
This is my setup

middleware.ts

module.exports = [
‘strapi::errors’,
{
name: ‘strapi::security’,
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
‘connect-src’: ["‘self’", ‘https:’],
‘img-src’: [
“‘self’”,
‘data:’,
‘blob:’,
dl.airtable.com’,
.digitaloceanspaces.com’,
],
‘media-src’: [
“‘self’”,
‘data:’,
‘blob:’,
dl.airtable.com’,
'
.digitaloceanspaces.com’,
],
upgradeInsecureRequests: null,
},
},
},
},
‘strapi::cors’,
‘strapi::poweredBy’,
‘strapi::logger’,
‘strapi::query’,
‘strapi::body’,
‘strapi::session’,
‘strapi::favicon’,
‘strapi::public’,
];

plugins.ts

module.exports = ({ env }) => ({
upload: {
config: {
provider: “strapi-provider-upload-do”,
providerOptions: {
key: env(‘DO_SPACE_ACCESS_KEY’),
secret: env(‘DO_SPACE_SECRET_KEY’),
endpoint: env(‘DO_SPACE_ENDPOINT’),
space: env(‘DO_SPACE_BUCKET’),
folders: [{folderName: ‘courses’, acl: ‘private’}, {folderName: ‘members’, acl: ‘private’}],
acl: ‘public-read’, // default ACL
},
actionOptions: {
upload: {},
uploadStream: {},
delete: {},
},
},
},
});

and this is the error message I got

Error: getaddrinfo ENOTFOUND strapi-fe-bucket

Thanks in advance!
Any help will be highly appreciated

Does anyone know how I can enforce the upload into a particular folder on DO using aws s3 plugin? I wanna upload from strapi media library always into a particular folder in the digital ocean spaces. Setting directory: “folder_name” does not seem to work.

I don’t know if this will fix your problem, but you list the config files as .ts but the code is for a javascript project. You should use this code for the config files:

export default ({ env }) => ({
  upload: {
config: {
provider: “strapi-provider-upload-do”,
providerOptions: {
key: env(‘DO_SPACE_ACCESS_KEY’),
secret: env(‘DO_SPACE_SECRET_KEY’),
endpoint: env(‘DO_SPACE_ENDPOINT’),
space: env(‘DO_SPACE_BUCKET’),
folders: [{folderName: ‘courses’, acl: ‘private’}, {folderName: ‘members’, acl: ‘private’}], 
acl: ‘public-read’, // default ACL
},
actionOptions: {
upload: {},
uploadStream: {},
delete: {},
},
},
}
});

Also I have no idea if the folders property is actually supported by DO or the upload provider.

To upload media to Digital Ocean Spaces, there are several options available. One option is to use the web interface provided by Digital Ocean Spaces. Simply log in, navigate to the desired Space, and click the “Upload” button to select and upload your media files.

Another option is to use a third-party tool like Gs Richcopy 360 or Goodsync. These tools offer more advanced features like automatic file synchronization and transfer acceleration. To use these tools, you’ll need to first set up a connection between your local computer and Digital Ocean Spaces using the appropriate credentials. Once the connection is established, you can use the software to select and upload your media files to the desired Space.

I’m having the same issue but resetting the key doesn’t work for me. This was working okay.

middlewares.js

module.exports = [
    'strapi::errors',
    {
        name: 'strapi::security',
        config: {
          contentSecurityPolicy: {
            useDefaults: true,
            directives: {
              'connect-src': ["'self'", 'https:'],
              'img-src': [
                "'self'",
                'data:',
                'blob:',
                'dl.airtable.com',
                '*.nyc3.digitaloceanspaces.com',
                'nyc3.digitaloceanspaces.com',
              ],
              'media-src': [
                "'self'",
                'data:',
                'blob:',
                'dl.airtable.com',
                '*.nyc3.digitaloceanspaces.com',
                'nyc3.digitaloceanspaces.com',
              ],
              upgradeInsecureRequests: null,
            },
          },
        },
      },
    'strapi::cors',
    'strapi::poweredBy',
    'strapi::logger',
    'strapi::query',
    'strapi::body',
    'strapi::session',
    'strapi::favicon',
    'strapi::public',
  ];

plugins.js

module.exports = ({ env }) => ({
    upload: {
      config: {
        provider: 'aws-s3',
        providerOptions: {
          accessKeyId: env('DO_ACCESS_KEY_ID'),
          secretAccessKey: env('DO_ACCESS_SECRET'),
          endpoint: env('DO_ENDPOINT'), // e.g. "s3.fr-par.scw.cloud"
          params: {
            Bucket: env('DO_BUCKET'),
          },
        },
      },
    },
  });

ERROR:

 [2023-05-31 16:00:32.652] error: SignatureDoesNotMatch: null

I’ve tried regenerating the key and also using a different key. Also re building and re deploying the app.

I’m kinda lost on where to look for an error, any ideas?

Tip: for a specific directory add the directory name to the bucket name in the DO_BUCKET variable
[bucket_name]/[directory_name]

providerOption ‘directory’ doesn’t works with aws-s3

Hey Everyone,
So I followed the steps above from @Shaun_Brown’s post with testDOnovember and everything seems to be working on my local machine/environment, I’m able to upload and delete images but when I try deploying to DigitalOcean, I keep getting "Could not load upload provider ‘aws-s3’ ". Has anyone ever run into this issue while trying to deploy? Here’s the stacktrace:

[2023-11-16 13:28:21] [2023-11-16 13:28:21.991] debug: ⛔️ Server wasn't able to start properly.
[2023-11-16 13:28:21] [2023-11-16 13:28:21.993] error: Could not load upload provider "aws-s3".
[2023-11-16 13:28:21] Error: Cannot find module 'aws-s3'
[2023-11-16 13:28:21] Require stack:
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/plugin-upload/server/register.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/plugin-upload/server/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/plugin-upload/strapi-server.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/utils/dist/import-default.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/utils/dist/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/data-transfer/dist/utils/components.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/data-transfer/dist/strapi/queries/entity.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/data-transfer/dist/strapi/queries/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/data-transfer/dist/strapi/providers/local-destination/strategies/restore/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/data-transfer/dist/strapi/providers/local-destination/strategies/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/data-transfer/dist/strapi/providers/local-destination/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/data-transfer/dist/strapi/providers/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/data-transfer/dist/strapi/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/data-transfer/dist/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/strapi/dist/commands/index.js
[2023-11-16 13:28:21] - /workspace/node_modules/@strapi/strapi/bin/strapi.js
[2023-11-16 13:28:21]     at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15)
[2023-11-16 13:28:21]     at Module._load (node:internal/modules/cjs/loader:901:27)
[2023-11-16 13:28:21]     at Module.require (node:internal/modules/cjs/loader:1115:19)
[2023-11-16 13:28:21]     at require (node:internal/modules/helpers:130:18)
[2023-11-16 13:28:21]     at createProvider (/workspace/node_modules/@strapi/plugin-upload/server/register.js:53:16)
[2023-11-16 13:28:21]     at module.exports [as register] (/workspace/node_modules/@strapi/plugin-upload/server/register.js:16:38)
[2023-11-16 13:28:21]     at Object.register (/workspace/node_modules/@strapi/strapi/dist/core/domain/module/index.js:49:52)
[2023-11-16 13:28:21]     at Object.register (/workspace/node_modules/@strapi/strapi/dist/core/registries/modules.js:29:27)
[2023-11-16 13:28:21]     at async Strapi.runLifecyclesFunctions (/workspace/node_modules/@strapi/strapi/dist/Strapi.js:509:9)
[2023-11-16 13:28:21]     at async Strapi.register (/workspace/node_modules/@strapi/strapi/dist/Strapi.js:428:9)
[2023-11-16 13:28:22] npm notice 
[2023-11-16 13:28:22] npm notice New minor version of npm available! 10.1.0 -> 10.2.4
[2023-11-16 13:28:22] npm notice Changelog: <https://github.com/npm/cli/releases/tag/v10.2.4>
[2023-11-16 13:28:22] npm notice Run `npm install -g npm@10.2.4` to update!
[2023-11-16 13:28:22] npm notice 

frankly this is why Strapi needs to get serious or they will lose developers? Seriously, after so mnay yeasr we dont have a working media library for Digital Ocean… not all can go to cloud because of the bandwidth costs. Many of us like myself would like to start with self hosted on Digital Ocean and later get an enterpise license should things prove profitable… BUT inspite of being a great tool, strapi dev experience is lacking

I was experiencing the same problem with missing HTTPS using Strapi v 4.16.2 and strapi-provider-upload-do v 3.6.9 connected to DigitalOcean. I fixed it by my migrating to strapi/provider-upload-aws-s3 v 4.20.0, with the following plugins.ts;

image