This Ghost blog is hosted on an Amazon EC2 linux instance. Storing your static image files on an ephemeral, virtual file system is risky. If the web server takes a nosedive? Poof ... your images be gone. I thought about using an EBS volume to persistently store images but that seemed like overkill.

Another option would be to store blog post images in a GitHub repo along my theme files. However, that's not ideal because over time it would bloat the size of the repository. The only images I keep in GitHub are those that are part of the theme itself.

Fortunately there's an NPM module that auto-magically uploads and serves up your blog post images from Amazon S3.

SSH into your Ghost server and change directories to the root of your Ghost installation.

$ ssh

$ cd /path/to/ghost

Install the ghost-s3-storage module. Note depending on your environment you may have to run this command with --production.

$ npm install --save ghost-s3-storage

Change directories to your content folder:

$ cd /path/to/ghost/content

Create the server side JavaScript file that enables the custom Ghost storage module.

$ mkdir storage

$ cd storage

$ mkdir ghost-s3

This file path should exist after you run the commands above.


Now create an index.js file in the directory above with these 2 lines.

'use strict';
module.exports = require('ghost-s3-storage');

Create a new bucket in your S3 account with read/write permissions for "authorized users". Then create an IAM user authorized to read/write to the new bucket. You'll get an accessKeyId and secretAccessKey when you create the IAM user.

Edit your Ghost config.js file. I'm using the nano text editor for this example.

$ nano /path/to/ghost/config.js

Edit the development {} and/or production {} blocks and include the following.

storage: {
    active: 'ghost-s3',
    'ghost-s3': {
        accessKeyId: 'Put_your_access_key_here',
        secretAccessKey: 'Put_your_secret_key_here',
        bucket: 'Put_your_bucket_name',
        region: 'Put_your_bucket_region'

Now restart the NodeJS process running your Ghost blog. I use PM2 to manage node processes on my server so your command may differ.

$ pm2 restart ghost