Dokku, oh, it is my favorite self-hosted deployment software for personal and sometimes commercial needs. It has its flaws but overall it works in most situations and allows me to save some money, so I use it for my pet-projects and for my website too.
Before we start, I assume you've already installed Dokku on your server, configured all the things properly, installed dokku-mysql, created a new database (ex: ghost-db), created a new app for Ghost, let's call it simply ghost and linked them.
As of v0.24.0 Dokku allows to deploy Docker images using a straightforward command, before this it was a nightmare with tagging.
dokku git:from-image node-js-app dokku/node-js-getting-started:latest
So, dokku git:from-image is exactly what we need.
We are going to use Docker Ghost image that can be found here. You can use any of the tags, but it is fine to use :latest for initial deployment.
dokku git:from-image ghost ghost:latest
This will build your app using the image you provided and then deploy it using your Dokku settings. By the end of the process you will have a working Ghost instance without any persistance and wrong public ports.
Here we are going to make Ghost app public by adding some new ports and removing those that we don't need.
dokku proxy:ports-add ghost http:80:2368 dokku proxy:ports-remove ghost http:2368:2368
By the end of this step your Ghost app should now be accessible via a domain you provided initially to Dokku or via port mapping.
Docker images do not keep any data between restarts, that's why we should provide some persistant volumes to it. Dokku allows us to do this easily via storage:mount command.
dokku storage:ensure-directory ghost dokku storage:mount /var/lib/dokku/data/storage/ghost:/var/lib/ghost/content dokku ps:rebuild ghost
In this step we create a new folder ghost in a special place where Dokku docs suggests us to keep persisted data, then we use our new folder /var/lib/dokku/data/storage/ghost to keep Ghost data from docker image folder /var/lib/ghost/content. This way everything that Ghost creates and keeps in this content folder will be persisted between reloads.
Ghost can work even without a separate database, using a SQLite and keeping it on the disk, I don't really like it but if you are okay with this, then skip this step. Before we even started, you already installed dokku-mysql and created a database for Ghost, we will need it here.
dokku config:set \ database__client=mysql \ database__connection__database=<YOUR_DATABASE_NAME> \ database__connection__host=<YOUR_DATABASE_HOST> \ database__connection__password=<YOUR_DATABASE_PASSWORD> \ database__connection__port=<YOUR_DATABASE_PORT> \ database__connection__user=mysql
In this step we provide some essential database configuration params to the Ghost app, as you set them, Dokku will restart it and it should then work using mysql database.
One of the main things we should do, is to add a domain to our app, Dokku has some useful commands for this.
dokku domains:add ghost my.ghost.website dokku config:set ghost url=http://my.ghost.website
You need SSL certificate for your website. With Dokku you can add it in several ways, using official Let's Encypt plugin, or using your own certificate, or using a Cloudflare SSL. Any of these do, but don't neglect this step.
Just don't forget to change your website url in configs.
dokku config:set ghost url=https://my.ghost.website
That's it, by now you have a working website powered by Ghost and deployed using Dokku on your own server for little to no money 🪄🦄✨.