Strapi wants us to create a public s3 bucket to use for media files. The setup with a public bucket is pretty easy [documentation]. First do everything as said in this [documentation], just don't enable the public access option. Also, make sure ACL option is enabled
Sometimes you may require to use only a private bucket because a public S3 bucket would be a security risk in terms of DDOS attacks etc. Let's see how we can do this.
Step 1: Custom Provider
For this, we will write our upload provider. You may take a look at the strapi docs too.
"@strapi/provider-upload-aws-s3": "^4.1.5", in your
After this run
In your project root directory, create a folder
providers. Inside that create another folder
upload-custom-provider. In that folder, you will need two files like it's shown in the below image.
Go to this path and copy these two files and put them in your
Open index.js (which is inside custom-provider folder), somewhere around line no 27 you will see
ACL: 'public-read',. Replace
Step 2: Setup custom provider
If you have already done the setup for the s3 bucket in strapi your plugin.js must be looking like this. just make sure you are using the new
provider: 'custom-provider',, not the default
Now, in package.json (which is in the project root directory) replace
"@strapi/provider-upload-aws-s3": "^4.1.5", with this
Keep all these credentials in your
AWS_ACCESS_KEY_ID=<value> AWS_ACCESS_SECRET=<value> AWS_BUCKET_NAME=<value> AWS_REGION=<value>
Step 3: Almost done
If you run
npm install and then
npm run develop you will be able to upload in the private bucket now. But as the bucket objects are private the images will not be able accessible.
After upload, the images will look like this.
if you try to open the images in a new tab, you will see an access denied error. But make sure the images are there in the bucket.
Step 4: CloudFront distribution setup
I don't have the exact steps for this setup but you can follow the AWS documentation or this below tutorial that I found on youtube.
Once this setup is done you will get a CloudFront base URL to assess the images publically.
The URL will look something like this
Now, all we have to do is replace the s3 bucket base URL with the CloudFront base URL to access the images. Open index.js again and do the placement. see line no 37 in the below image.
file.url = data.Location.replace(process.env.AWS_RESOURCES_BASE_URL, process.env.AWS_CLOUDFRONT_BASE_URL);
Add these two values in the env file.
After this everything should work smoothly.
Hope this helps. If you find any better solution or have any suggestions please comment below. I would love to hear from you guys.