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.
beers!