Installing Ghost on Dokku

Ghost doesn't recommend installing on Heroku because it has an ephemeral file system. All this actually means of course is a little extra configuration, and How To Install Ghost has come up with a great guide on how to do it using S3 storage.

Dokku is an awesome project that recreates a Heroku like experience on your own server. It's very easy to setup on DigitalOcean, and ends up being alot cheaper than Heroku.

Since the two platforms are similar, most of the instructions from How To Install Ghost are useful in setting up Ghost on Dokku. But it isn't a direct mapping, and I wanted to do it without using AWS S3. So I thought I'd make a guide for installing on Dokku, using the storage plugin to get around the filesystem problem.


Setup your app in Dokku –

# On your server
dokku apps:create test-blog  

Then, grab a copy of ghost and set it up as a git repository with your Dokku remote.

# Setup a new repository
git init  
git remote add dokku dokku@SERVER.com:test-blog  

Basic Configuration

Start by copying config.example.js to config.js. Then you'll need to make some changes to the server configuration -

server: {  
    host: '127.0.0.1',
    port: '2368'
}

Dokku provides a PORT environment variable that we want to configure Ghost to serve on. We also need it to not just serve on localhost (127.0.0.1). It should look like this -

server: {  
    host: '0.0.0.0',
    port: process.env.PORT
}

Database Setup

Now we need to setup a database - we'll use MySQL just because it's so common and has first class support in Ghost, but the Postgres plugin is a similar setup process.

If you don't have the Dokku MySQL plugin yet –

dokku plugin:install https://github.com/dokku/dokku-mysql.git mysql  

Then you can easily setup a database container and link it -

# Create a test database 
dokku mysql:create test-blog-db

# Link it to our app 
dokku mysql:link test-blog-db test-blog  

That will export a nice DATABASE_URL environment variable into your container, which we can read from our config.js file like this –

database: {  
    client: 'mysql',
    connection: process.env.DATABASE_URL,
    debug: false
}

You should now be able to successfully deploy the app -

git add .  
git commit -m "Initial"  
git push dokku master`  

Depending on your Dokku installation, it'll either show up at an IP address and port combination, or something like test-blog.mysite.com.

Storage

Your app should be deployed and accessible, but if you upload any images, they'll disappear. Which isn't ideal, so we'll use the Dokku storage command to link some directories to persistent storage outside the container.

Dokku recommends that we use the /var/lib/dokku/data/storage for our mounts –

# Configure
dokku storage:mount test-blog /var/lib/dokku/data/storage/test-blog:/app/content/images

# Redeploy the app for the changes to take effect 
dokku deploy test-blog

# You should now see a test-blog directory 
ls /var/lib/dokku/data/storage  

Your images should now happily withstand container restarts. Of course if you prefer, you can also follow the HTIG instructions to store them on AWS S3 instead.

That's it! There are of course plenty of other things you can do to trick out your Dokku Ghost installation, like using the Let's Encrypt plugin to secure your site.

Happy blogging!