Ghost up and running in Docker

This is mainly for documenting the process for getting this blog thing up and running on my server.
When looking for potential blog software and researching cms systems I stumbled over ghost quite early. Starting in 2013 ghost aimed to be a fairly minimal cms for quick and easy blog setups.
Since I was looking for something like this, I decided to give it a try. Another big plus for me is the possibility to run the whole setup in Docker. I like the basic pattern of running services in containers on my server exposed locally and use nginx as reverse proxy to foreward the traffic to those services.
Lets see what we need to do.
First of lets make sure we have docker installed and running.
$ docker --version
Docker version 23.0.1, build a5ee5b1
When using containers the storage is usually ephemeral, that means when the container is stopped for whatever reason the data is gone. We do not want this for our blog so we have to put in some persistence for storing the data.
# creating the volume for our blog itself
docker volume create ghostblog
# creating the volume for the blog database
docker volume create ghostblogdb
We can now start setting up a docker-compose file where the configuration of our containers will happen.
TLDR;
this is the whole file which I used which should work, when the volumes were created beforehand. Following we will take a look into separate parts of this.
version: '3'
services:
ghost:
image: ghost:5-alpine
restart: always
ports:
- "127.0.0.1:8888:2368"
environment:
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: myS3cur3Pa$$W0rd)
database__connection__database: ghost
url: https://this-should-be-your-url.tld/
volumes:
- ghostblog:/var/lib/ghost/content
depends_on:
- db
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: myS3cur3Pa$$W0rd)
volumes:
- ghostblogdb:/var/lib/mysql
volumes:
ghostblog:
ghostblogdb:
In the first part we define the service ghost itself. The important part can be found in the environment section.
Ghost itself can be configured via environment variables, where nested keys can be combined via two underscores with their top level keys. We define in our setup mainly the database options and the important key which defines our url.
When this is not set correctly ghost will fail to preview your site in the admin and editor area.
Setting the password can be probably also done via Docker Secrets. This has to be created beforehand and needs a separate declaration in the docker-compose.yaml. There is a pretty good blog entry on this by Allan MacGregor on Earthly.
However since this database is running only locally exposed and I do not put this file under version control, I consider this as 'secure enough'.
[...]
environment:
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: myS3cur3Pa$$W0rd)
database__connection__database: ghost
url: https://this-should-be-your-url.tld/
volumes:
- ghostblog:/var/lib/ghost/content
depends_on:
- db
Also we define the volume which was created in the beginning where our content will be stored. I added the for the dependency because when experimenting with the setup I saw very often error messages of ghost itself in the log, that the database connection failed, which came due to the fact that the container was not running yet.
When starting up those containers you should be able to access the ghost default interface on your localhost on port 8888.
In the next part, we will take a look how this works all together with nginx as reverse proxy.
credits
Image by Clker-Free-Vector-Images from Pixabay
https://hub.docker.com/_/ghost
https://ghost.org/docs/config/