DEV Community

Manu
Manu

Posted on • Originally published at manu.breton.ch on

Ghost in A shell - part IV (and final): Maintenance

Ghost in A shell - part IV (and final): Maintenance

One very good reason to go for Ghost(Pro) is that you do not have to maintain your blogs. They just run. For ever. Eventhough servers do crash, hard drives do break, electric power do fail, blogs do need to be upgraded... they will continue serving their pages.

Nevertheless, having one's own setup is fun (as long as you are aware of the limits above), and much easier to play with. You could for instance:

  • run the Ghost version you want:
$ GHOST_VERSION=1.10 PORT=3002 NAME=old make

$ NAME=old make cli-version
  docker exec -it old ghost -v
  Ghost-CLI version: 1.1.1
  Ghost Version (at /var/lib/ghost): 1.10.0
  Latest version on Docker Hub: 1.24.2

Enter fullscreen mode Exit fullscreen mode
  • maintain many blogs without having to remember the options they were built with:
# instead of 
$ PORT=3003 NAME=new URI=my-new-super-blog DOMAIN=me.com make restart

# just use
$ p=instances/new/ make restart

Enter fullscreen mode Exit fullscreen mode
  • upgrade your blog with no risk and no hassle
$ vi instances/old/.env
  GHOST_VERSION=1.24

$ make p=instances/old/ upgrade
  docker exec -it old ghost -v
  Ghost-CLI version: 1.8.1
  Ghost Version (at /var/lib/ghost): 1.24.2
  Latest version on Docker Hub: 1.24.2

Enter fullscreen mode Exit fullscreen mode

And these three reasons are good enough for me to write this fourth (and last) blog about shells of Ghost . Did I say "fourth" ? yep!. And here are the three first ones:

  1. Part I : localhost, that focuses on localhost
  2. Part II : HTTPs is the norm, that shows you how to spawn multiple ghost instances on a given server
  3. Part III: To production, with performance, that applies the recommendations from the Ghost team when it comes to DB + emailing, and puts a bit of pressure on the resulting instances

But first of all you need the basic diagnostic tools

Environment variables

We have seen before the two following commands

  • make ps to list the running instances
  • make logs to tail and follow the logs, i.e to see what is happening

Those commands depends on the environment vars, which can be overridden in the command line. E.g.:

  1. make vars will list for you the currently configured variables
$ make vars
# common
 NAME=ghost-local
 GHOST_VERSION=1
# values used for dev
 PORT=3001
# values used by traefik (qa & prod)
 PROTOCOL=http
 DOMAIN=localhost
 URI=ghost-local

Enter fullscreen mode Exit fullscreen mode
  1. NAME=my-blog URI=me PROTOCOL=https GHOST_VERSION=1.22 make vars will show how the variable are overriden
$ make vars
# common
 NAME=my-blog
 GHOST_VERSION=1.22
# values used for dev
 PORT=3001
# values used by traefik (qa & prod)
 PROTOCOL=https
 DOMAIN=localhost
 URI=me

Enter fullscreen mode Exit fullscreen mode

So far (in the previous blogs) this is the way to go with multiple instances... and it sucks, especially if you want to run different set of values for each of them (which is exactly the reason why we have this series in the first place)

All-in-one configurations

Therefore, there is a newcomer in the list of available variables: please welcome p.

p is the path of the valid instance of the blog you want to act upon. you can use it with most of the make commands we have seen so far.

Valid means that the path will contain a .env file with all the overriden variables. For the sake of your sanity, this file is automatically generated when you spawn your instances with make [dev|qa|prod]. e.g.:

$ NAME=new-blog PORT=3002 make
# Simply start a ghost container making it directly available through $PORT
docker run --rm -d --name new-blog \
        -v /Users/emb/git-repos/ghost-in-a-shell/instances/new-blog:/var/lib/ghost/content \
        -p 3002:2368 \
        -e url=http://localhost:3002 \
        ghost:1-alpine
6330f60a50a834c7acee5916751815e47bba2f68b98f150a6ba2fe59627704ff
make save-vars
creating instances/new-blog/.env

Enter fullscreen mode Exit fullscreen mode

The last two lines are the new sweetie... and you can now run the following to make sure your configuration as been saved:

$ make p=instances/new-blog/ vars
# common
  p=instances/new-blog/.env
  NAME=new-blog
  GHOST_VERSION=1
# values used for dev
  PORT=3002
# values used by traefik (qa & prod)
  PROTOCOL=http
  DOMAIN=localhost
  URI=new-blog

Enter fullscreen mode Exit fullscreen mode

Consequently

  • make p=instances/new-blog/ vars will list all vars from ./instances/new-blog/.env
  • make p=instances/new-blog/ logs will tail and follow the logs of the ./instances/new-blog blog instance
  • make p=instances/new-blog/ restart will restart the blog with the settings defined in ./instances/new-blog/.env
  • make p=instances/new-blog/ cli-version show the versions for the new blog
  • and so on...

Note that 1) the path is relative, 2) the trailing / is mandatory, but it should come with the bash autocompletion anyway. (that's why it is done like this)

Upgrade (and Downgrade)

Upgrading may be painful (particularly if you do not do it often enough). It is for sure scary. No ones want to change (break) something that runs smoothly.

You first need a bit of information, e.g with the question 'how far am I behind ?'. make cli-version will help you there:

$ make cli-version
docker exec -it ghost-local ghost -v
Ghost-CLI version: 1.8.0
Ghost Version (at /var/lib/ghost): 1.23.0
Latest version on Docker Hub: 1.24.2

Enter fullscreen mode Exit fullscreen mode

The upgrade mechanism relies on DockerHub tags. Which means that the most generic tags point to the latest version, and that the same version may have multiple tags. For instance, if the latest version is 1.24.2, you will get this version with all the following tags: 1.24.2, 1.24, 1, latest.

Hence the following behavior when upgrading:

  • GHOST_VERSION=1 -> will automatically update to all new releases of 1st version
  • GHOST_VERSION=1.x -> will automatically update for patches only
  • GHOST_VERSION=1.x.x -> will never automatically update

By default, the GHOST_VERSION is set to 1. Therefore, upgrading is as simple as make upgrade[-qa|-prod]. This command will pull the lastest (1.x.x) docker image and restart the container for you.

You can force your desired GHOST_VERSION by overriding the env var:

$ GHOST_VERSION=1.24 make upgrade
...
Ghost-CLI version: 1.8.0
Ghost Version (at /var/lib/ghost): 1.24.2
Latest version on Docker Hub: 1.24.2

Enter fullscreen mode Exit fullscreen mode

If you have specified a GHOST_VERSION when you created the blog instance, e.g: GHOST_VERSION=1.10 PORT=3002 NAME=old make, the version is stored in the .env file. Therefore the p helper variable will not allow you to upgrade automatically. It will stick to the version of the instance specified when it was created, e.g:

$ p=instances/old/ make upgrade
...
docker exec -it old ghost -v
Ghost-CLI version: 1.1.1
Ghost Version (at /var/lib/ghost): 1.10.0
Latest version on Docker Hub: 1.24.2

Enter fullscreen mode Exit fullscreen mode

You will have to edit manually your ./instance/$NAME/.env file and set the new GHOST_VERSION to upgrade it.

Would you like to rollback to a previous version, e.g. version 1.23.0? Just modify againt the .env file and upgrade again. Or pass the variables through the command line.

$ vi instances/old/.env
GHOST_VERSION=1.23.0

$ make p=instances/old/ upgrade
docker exec -it old ghost -v
Ghost-CLI version: 1.8.1
Ghost Version (at /var/lib/ghost): 1.23.0
Latest version on Docker Hub: 1.24.2

Enter fullscreen mode Exit fullscreen mode

the actual docker image downloaded is ghost:1.x.x-alpine: the -alpine suffix is added here because I prefer it lighter than heavier.

Reliability ?

Well, we have seen quite a lot with these series and reliability has more to do with the hosting you are going to choose. And security policies you are going to enforce too. Far too much and too wide for a simple tutorial like this one. Remember also the disclaimer from the begnining: go for Ghost pro if you are looking for reliability :)

Cheers,
Manu

Top comments (0)