Save images to Cloudinary when using Strapi and Heroku
Why
Like with project updates on Heroku, the file system doesn't support local uploading of files as they will be wiped when Heroku "Cycles" the dyno. This type of file system is called ephemeral, which means the file system only lasts until the dyno is restarted (with Heroku this happens any time you redeploy or during their regular restart which can happen every few hours or every day). Due to Heroku's filesystem you will need to use an upload provider such as AWS S3, Cloudinary, or Rackspace. You can view the documentation for installing providers here and you can see a list of providers from both Strapi and the community on npmjs.com
Before we start...
What is Strapi
Strapi is an open-source, Node.js based, Headless CMS that saves developers a lot of development time while giving them the freedom to use their favorite tools and frameworks. Strapi also enables content editors to streamline content delivery (text, images, video, etc) across any devices.
What is Heroku
Heroku is a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud. It supports several languages such as Java, Nodejs, Go, PHP, Python.
What is Cloudinary
Cloudinary is a cloud-based service offering features and APIs for uploading, storing, managing, and delivering media assets. When delivering assets, optimizations and other transformations can be applied to those assets based on options added to the delivery URLs.
We'll need the following:
- A strapi project on Heroku
- A strapi project on local
- A cloudinary account
- Nodejs v14+ installed
All the above are free
Setting up a Cloudinary account
Setting up a free tier account with Cloudinary is very straight forward. Just follow the on screen prompts until you are taken to your account dashboard.
We will need to take note of the following in the "Account details section" to use later:
- Cloud name
- API Key
- API Secret It goes without saying... Don't share these details with anyone
Adding cloudinary provider to Strapi
Make sure your Strapi server is not running before installing the cloudinary provider
yarn add strapi-provider-upload-cloudinary
Strapi config
Once the provider has finished being added to your project we will need to create ./config/plugins.js with the following:
module.exports = ({ env }) => ({
upload: {
config: {
provider: "cloudinary",
providerOptions: {
cloud_name: env("CLOUDINARY_CLOUD_NAME"),
api_key: env("CLOUDINARY_API_KEY"),
api_secret: env("CLOUDINARY_API_SECRET"),
},
actionOptions: {
upload: {},
delete: {},
},
},
},
});
Add keys to environment config
At the root directory create an .env file and replace "XXX" with your credentials. (Its under the Account Details section when you log in )
Its also worth double checking that this file to gitignore as it will contain sensitive information
CLOUDINARY_CLOUD_NAME=XXX
CLOUDINARY_API_KEY=XXX
CLOUDINARY_API_SECRET=XXX
Security Middleware Configuration
Due to the default settings in the Strapi Security Middleware you will need to modify the contentSecurityPolicy settings to properly see thumbnail previews in the Media Library. You should replace strapi::security string with the object bellow instead as explained in the middleware configuration documentation.
// ./config/middlewares.js
module.exports = [
// ...
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'https:'],
'img-src': ["'self'", 'data:', 'blob:', 'res.cloudinary.com'],
'media-src': ["'self'", 'data:', 'blob:', 'res.cloudinary.com'],
upgradeInsecureRequests: null,
},
},
},
},
// ...
];
Commit and push the changes after verifying that these changes are working locally.
Set up config vars on Heroku
You will need to add the config vars in Heroku:
- Log into your Heroku account
- Open your project
- Settings
- Config vars
- Reveal config vars
- Add your variable names here