Set up Amazon S3 Upload Provider Plugin for Your Strapi App

I am using Strapi v4. I am using S3 which is secured so there won’t be public access. I use a signed URL to access the S3. But the media library cannot be modified to display the preview with the signed URL and the media library cannot be modified so that when we copy the link will be signed.

Is there any way to modify the URL in the media library.

Hello,
thank you for the tutorial.
I succeeded to implement a custom aws upload provider with a custom url to get the thumbnail in the media library section using this line of code.

file.url = `${CDN}/${Key}/${file.hash}${file.ext}`

Right now strapi store the file.url inside the database, how i can say to strapi to not store the file url inside the database but instead use directly the environment variable when it display the thumbnails ?

FYI - if anyone else noticed the broken images in the markplace it’s due to the content security policy. Just add an additional line of code: 'https://market-assets.strapi.io/', to both image-src and media-src to fix this.

1 Like

I just wanted to add my 2 cents since I just spent a great deal of time on this. The instructions provided on how to do this are correct. I unfortunately had uploaded a ton of images before getting the instructions correct and did not have the ACL: env(‘AWS_ACL’, ‘public-read’) set in the plugins file earlier.

If this happens to you, the images will not be accessible and it will throw you for a loop if you have all the other settings correct everywhere. You have to mark the uploaded files ‘public-read’ in the S3 bucket. This can be done in different ways, but if you have files somewhere in 100-1000 count like I did, you can simple do it from the AWS console by selecting the files and marking them public-read ACL. Hope this helps someone!

1 Like

Thank you for the correction.

Hi All, I have strapi v4.20 and I am unable to upload files to the media library. I tried with 2 plugins first time with aws-s3 and second time with “local server”. It gives me the same error message like in the screenshot below with both the options.
image

when I inspect the response from the browser, I get a message error 403 with both the plugins above. Can someone help to point me the right direction to resolve this issue?

plugins.ts with local upload
export default ({ env }) => ({
upload: {
config: {
providerOptions: {
localServer: {
maxage: 300000
},
},
},
},
});

middleware.ts when with local and s3 upload option
export default [
‘strapi::logger’,
‘strapi::errors’,
‘strapi::cors’,
‘strapi::poweredBy’,
‘strapi::query’,
‘strapi::session’,
‘strapi::favicon’,
‘strapi::public’,

{
name: ‘strapi::security’,
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
‘connect-src’: [“‘self’”, ‘https:’],
‘img-src’: [
“‘self’”,
‘data:’,
‘blob:’,
market-assets.strapi.io’,
https://bucketname.s3.ap-southeast-1.amazonaws.com/’, //tried with various URL (with region, without region none works, same error)
],
‘media-src’: [
“‘self’”,
‘data:’,
‘blob:’,
market-assets.strapi.io’,
https://bucketname.s3.ap-southeast-1.amazonaws.com/’, //tried with various URL (with region, without region none works, same error)

      ],
      upgradeInsecureRequests: null,
    },
  },
},

},
// …

// …
{
name: “strapi::body”,
config: {
formLimit: “256mb”, // modify form body
jsonLimit: “256mb”, // modify JSON body
textLimit: “256mb”, // modify text body
formidable: {
maxFileSize: 250 * 1024 * 1024, // multipart data, modify here limit of uploaded file size
},
},
},
// …
];

pluginst.ts with s3 upload
module.exports = ({ env }) => ({
// …
upload: {
config: {
provider: ‘aws-s3’,
providerOptions: {
s3Options: {
accessKeyId: env(‘AWS_ACCESS_KEY_ID’),
secretAccessKey: env(‘AWS_ACCESS_SECRET’),
region: env(‘AWS_REGION’),
params: {
ACL: env(‘AWS_ACL’, ‘private’),
Bucket: env(‘AWS_BUCKET’),
},
},
},
actionOptions: {
upload: {},
uploadStream: {},
delete: {},
},
},
},
// …
});
.env
HOST=0.0.0.0
PORT=1337
APP_KEYS=xxxxx
API_TOKEN_SALT=xxxxx
ADMIN_JWT_SECRET=xxxxxx
TRANSFER_TOKEN_SALT=xxxxx

Database

DATABASE_CLIENT=mysql
DATABASE_HOST=xxxx
DATABASE_PORT=3306
DATABASE_NAME=strapi
DATABASE_USERNAME=xxx
DATABASE_PASSWORD=xxx
DATABASE_SSL=true
JWT_SECRET=xxxx
#AWS-S3-Bucket-to-upload-assets
AWS_BUCKET_NAME=strapi-poc-bucket
AWS_REGION=ap-southeast-1
AWS_ACCESS_KEY_ID=xxxx
AWS_ACCESS_SECRET=xxxx
CORS_ALLOWED_ORIGINS=[“*”]

This actually worked for me, but is there anything i can do which will help me upload inside a folder in s3 bucket. Coz right now the images are directly going on the root of the bucket…

Facing same problem

I faced the same problem because I forgot to add ENV variables to the production.

Adding those variables fixed it for me.