Save images to Cloudinary when using Strapi and Heroku


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


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


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:', ''],
          'media-src': ["'self'", 'data:', 'blob:', ''],
          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:

  1. Log into your Heroku account
  2. Open your project
  3. Settings
  4. Config vars
  5. Reveal config vars
  6. Add your variable names here

Screenshot 2022-01-19 141753.jpg