Upgrading the Ghost - Whoopi

Upgrading the Ghost - Whoopi

Ok - well my blog was telling me that a new version of Ghost was available... ummm, is it a gasp security update??? Who knows - the Ghost announcement gives narry a hint :(

So my paranoid submind says - Go for it, ASAP! - and foolishly I did.

My installation is multi-tenanted - I currently have four blogging sites. Three of them are solitary musing (Te Reo totahi doanchano), and one is a multi-user family blog.

Take a Backup

Yes sir-ee, backups block bad blowups!

Yikes - each Ghost folder is 200MB... oh and almost all of that is in locale-data - grrr, those Ghostly developers didn't design the product with clean separation (it's a concern!) of data and code. Typical - Devs never pay attention to Ops.

Maybe I can backup the content folder? that looks more interesting - ummm but it contains the static, user-cannot-change themes, hmmmm. So lets fix that first...

cd /var/www/normus.totahi.com/ghost/content
mkdir /var/www/ghost-themes     # /usr/share/ghost-themes might be better
mv themes ../../ghost-themes
ln -s themes ../../ghost-themes/themes

Oh - and it seems that config.js is important (sic!) - so let's get that into the content folder for easy backup, and while we're at it, we will prevent it from being accidentally borked (blush).

mv ../config.js .
chattr +i config.js
cd ..
ln -s content/config.js

But wait - argh, the blog is not working, because of a nasty in config.js - content is by default located relative to the config.js rather than the pwd, sigh.

  //filename: path.join(__dirname, '/content/data/ghost.db')
  filename: './content/data/ghost.db'

That's better - I can now backup each /var/www/*/ghost/content folder - and I have the config.js, content including images, but excluding the themes.

/me pootles off and scripts the backup, archive, offsite and monitoring for spec /var/www/*/ghost/content backups - job done!

So instead of creating 800MB backups, and then archives and offsite copies of the same, I have just 10MB of beautiful blog backups to manage - backup bliss.

Multiple Concurrent Versions

So one-blog-at-a-time upgrades... from 0.8.0 to 0.9.0 - not too stale, should be a cinch?

I had foolishly followed the Installing Ghost instructions plastered all over the web, so I had four installations - each an independent 200MB copy!

Here's the lowdown:

cd /var/www

# get the new version
wget https://ghost.org/zip/ghost-0.9.0.zip
unzip ghost-0.9.0.zip -d ghost-0.9.0

# This is going to be the shared master copy.
# I ran the install in an existing installation - but that failed
# with a version-issue on one of the dependencies (an npm2 bug).
# Running install in a pristine installation works, and prepares
# the ground for a shared node_modules.

cd ghost-0.9.0
npm install --production

# upgrade one site first...
cd /var/www/normus.totahi.com/ghost

# shut down just this instance - yeah, I should script this
grep port config.js # listening on 2368
netstat -leapn | grep 2368 # pid/node
kill 509940
# sho nuff, blog is showing as 502-bad-gateway

# move version 0.8.0 copy sideways into an old folder...
mkdir old
mv config.example.js core Gruntfile.js index.js LICENSE node_modules npm-shrinkwrap.json package.json PRIVACY.md README.md old

# Create links and install copies of 0.9.0
# Note that core and index.js MUST be copies to work - grrr
# Others can be linked
cp -rp ../../ghost-0.9.0/core .
cp ../../ghost-0.9.0/index.js .
ln -s ../../ghost-0.9.0/node_modules
ln -s ../../ghost-0.9.0/npm-shrinkwrap.json
ln -s ../../ghost-0.9.0/package.json

# Start npm foreground so we can check for errors...
# It will fail with a meaningless message if an old instance is
# still listening...
npm start --production

# It runs a migration, no warnings - fingers crossed...
# Woohoo - blog is up and GRADED!

# TODO: schedule cleanup old in a weeks time...
# rm -rf /var/www/*/ghost/old

We now have the following for our working 0.9.0 site:

ls -l
lrwxrwxrwx ... config.js -> content/config.js
drwxr-xr-x ... content
drwxr-xr-x ... core
-rw-r--r-- ... index.js
lrwxrwxrwx ... node_modules -> ../../ghost-0.9.0/node_modules
lrwxrwxrwx ... npm-shrinkwrap.json -> ../../ghost-0.9.0/npm-shrinkwrap.json
lrwxrwxrwx ... package.json -> ../../ghost-0.9.0/package.json

Repeat and rinse for the remaining three installations...

# let's make sure that the daemonisation is also a happy little devil...
service ghost restart

# test read access to all four blogs
# Whoopi - happy bunny, Golden(burg)

Memo to a Ghost

  • It's a fantastic product - bowler off to ya'all - these are mere pittances in the panoply of the software blogoshpere.
  • Making everything run from a single working-directory is a good idea... but let down by a few bugs
    • config.js - content is relative to the location of config.js rather than pwd
    • core - same - something assumes relative-to-file rather than pwd, preventing this being shared
    • index.js - ditto - something relative-to-file rather than working-directory
  • Backups - use the Admin interface? really?
    • Please feel free to volunteer to do this for me every morning at 2:00am, even when I am on holiday.
    • We need a script to extract the time-stamped .json - preferably into the content folder so I can easily cron and backup.
  • Still love ya!

Tweaking in the Twilight Zone

I decided to move the ghost software and themes out of the Webserver document root - though that concept is a bit moot here, as there isn't really one.

I relocated the ghost software to /usr/share

# TODO: re-read the FSB... again
# /usr/share/ghost-0.8.0 
# /usr/share/ghost-0.9.0 
# /usr/share/ghost-themes

ls -l 
lrwxrwxrwx ... config.js -> content/config.js
drwxr-xr-x ... content
drwxr-xr-x ... core
-rw-r--r-- ... index.js
lrwxrwxrwx ... node_modules -> /usr/share/ghost-0.9.0/node_modules
lrwxrwxrwx ... npm-shrinkwrap.json -> /usr/share/ghost-0.9.0/npm-shrinkwrap.json
lrwxrwxrwx ... package.json -> /usr/share/ghost-0.9.0/package.json

tidier - satisfies my obsessive-compulsive submind.