Using Cloudinary with Ghost

by Jason on

Update: Looks like Ghost will support this sort of thing through the App API. Keeping this around in case anyone needs it before that feature goes live.

Decided to take Ghost for a spin. My testbed for that kind of thing is typically AppFog.

Installation was pretty simple. (Here’s a snippet of my Ghost config that I got running on AppFog for anyone who might be looking for this sort of thing. Ignore the storage section unless you read on.)

So it’s alive, running and woohoo! But then I uploaded a cat picture (are there any other kinds?), restarted the application and my picture was gone. It was then I remembered:

No persistent file storage on AppFog

This is a big problem. I can’t upload pictures of cats! Wha? What’s the use of a blog anyway without that functionality! However let me be clear this is an AppFog problem, not a Ghost problem. AppFog has been working on “persistent file storage” for well over a year now.

Ghost is easily extendible and this is a solvable problem. We could use Cloudinary, Amazon, Rackspace or any other cloud to solve the problem. I settled on Cloudinary as it was mentioned in the Ghost to Wordpress migration plugin.

My additions to support Cloudinary in Ghost are in this pull request. Check it out if you’re facing the same issue and want get around AppFogs problems or if you want to extend Ghost support to more cloud providers.

My config for Ghost on AppFog: (my changes from the default highlighted in blue.)

// # Ghost Configuration
// Setup your Ghost install for various environments
// Documentation can be found at
var path = require('path'),

var mysqlCred = {};
if (process.env.NODE_ENV === 'production') {
    mysqlCred = (JSON.parse(process.env.VCAP_SERVICES || '{}')["mysql-5.1"] || [{}])[0].credentials;

config = {
    // ### Production
    // When running Ghost in the wild, use the production environment
    // Configure your URL and mail settings here
    production: {
        url: '',
        mail: {},
        database: {
            client: 'mysql',
            connection: {
                host     :,
                user     : mysqlCred.user,
                password : mysqlCred.password,
                database :,
                charset  : 'utf8'
            debug: false

        server: {
            // Host to be passed to node's `net.Server#listen()`
            host: process.env.VMC_APP_HOST || '',
            // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
            port: process.env.VMC_APP_PORT || 1337
        storage: {
            type: 'cloudinary-file-store',
            credentials: {
                cloud_name: '',
                api_key: '',
                api_secret: ''