Self Hosted Ghost Blog setup with Docker
How to set up a self-hosted ghost blog with docker, mysql, TLS, and backup script.
Just recently updated this blog itself to latest version of Ghost running via docker-compose
. The blog itself is TLS enabled and backed up the content to S3 periodically. This is my public note on how. In case anybody would find it useful.
Ghost docker hub page is a great place to get started. I added to it to get what I needed. Namely a backup and TLS proxy.
The server
The example used here are based on Ubuntu 18.04. We also needed to install docker on the host. The steps are detailed in the excellent guide below.

Make sure to open firewall on port 80
and 443
. Port 80 won't be doing much, just a redirect to 443
.
The services
The docker-compose.yml
file below has 3 services
ghost – This is the ghost server itself. Runing on port 2368. Mounted the content directory (mainly images) to the host /var/lib/ghost/content
.
db – The mariadb server that ghost server writes to. Change MYSQL_ROOT_PASSWORD
to match what ghost server expects
caddy - Our TLS proxy from outside world to our ghost server. This is a much easier route compared to fiddling with nginx and certbot. Make sure to put Caddyfile
in /home/ubuntu/caddy/config/Caddyfile
to configure the domain name and reverse proxy port correct.
Backup Script
The script tar-up a mounted content directory and calls to MySQL to dump a database. Then it proceeds to upload the result file to S3.
The script assumes there's an aws-cli
installed with a profile called backup
set up. On Ubuntu this could be as simple as.
$ sudo apt-get install awscli
$ aws configure --profile backup
AWS Access Key ID [None]: <keyname>
AWS Secret Access Key [None]: <secret>
Default region name [None]: <region>
Default output format [None]: yaml
Then put this script in /home/ubuntu/daily_backup.sh
Compared to previous method
The site used to be created via Digital Ocean Marketplace. Although simple and very easy to get started, I was stuck at the (rather old) version. Ghost is still very much in active development. Updating ghost sometimes means update version of NodeJS which may not be as simple when your base OS gets older.