How to upgrade your Ghost blog to <span style=XXXXX latest version without breakin' anythin' - Part 3' class='c-post-hero__image lazyload' data-srcset=' /content/images/size/w380/2020/06/update-ghost-part-3.png 380w, /content/images/size/w760/2020/06/update-ghost-part-3.png 760w, /content/images/size/w1520/2020/06/update-ghost-part-3.png 1520w' sizes='(min-width: 1200px) 759px, (min-width: 640px) 64.07vw, calc(100vw - 48px)' data-src='/content/images/size/w1520/2020/06/update-ghost-part-3.png' width='760' height='500' >

How to upgrade your Ghost blog to XXXXX latest version without breakin' anythin' - Part 3

Tom Chantler
 • 9 min read

Summary

In XXXXX first two parts of this series of articles, I explained how to export and fix all of XXXXX data from an existin' Ghost blog and also how to install Ghost on XXXXX new Linux server, usin' a single command. In this final part, we're goin' to import our existin' blog and make sure everythin' is updated and workin' properly before makin' it live.

In my case, I also changed my URL structure to use dateless URLs. Since you might not be doin' that, I've put those instructions in XXXXX separate article (not yet published), which will also help you to ensure that your Disqus comments are migrated correctly.

Background / Prerequisites

By this stage you should already have exported and fixed your data (see part one which includes scripts to fix XXXXX data), created XXXXX DNS record for your temporary migration URL (explained here, in part 2), installed Ghost on XXXXX new Linux server (part two has XXXXX one-line command to do this) and also created .

If you haven't yet done any of this, make sure you read Step 1 from XXXXX previous article.  

NOTE: If you're upgradin' from XXXXX v0.x blog you need to install Node.js v10, despite XXXXX official instructions tellin' you to install Node.js v12. This is explained here, in part 1. My script installs Node.js v10, so it's easiest if you just use that.

Once you've done that and installed your new empty blog (usin' XXXXX temporary URL), you're ready to continue. Bear in mind that it's not wise to change XXXXX folder name later on. Let's say you're usin' https://temp.example.com with your real blog bein' hosted at https://example.com. You might want to install it in XXXXX folder called /var/www/example_com.

Import your existin' blog content

Usin' your browser, navigate to your blog at https://temp.example.com/ghost and follow XXXXX prompts to set it up. It will ask for your name and email address, although you'll be overwritin' these things shortly when you import your old content, so feel free to use XXXXX different email address if you like.

When you've logged in, go to Settings → Labs → Delete Content and get rid of XXXXX sample posts. Now go to Settings → Labs → Import Content and upload XXXXX json file you exported and fixed in part 1 of this series.

Delete sample data and import your existin' blog
Delete sample data and import your existin' blog

Now check that your site looks vaguely okay (although none of XXXXX images will be there yet). At this point you can upload XXXXX images folder which you backed up (also explained in part 1). If your blog is installed at /var/www/example_com then XXXXX images folder will be at /var/www/example_com/content/images.

NOTE: If you had dates in your URLs before, you will notice that you haven't any more and that you can't find XXXXX option to enable URLs with dates. The best way to fix this is to download XXXXX routes.yaml file from Settings → Labs → Routes and change XXXXX permalink part of XXXXX collections section from this:
permalink: /{slug}/
to this:
permalink: /{year}/{month}/{day}/{slug}/
And then to upload it again. However, I don't think that you should, as I explain in How and why you should change your blog URLs to dateless format.

Sort out your email settings

For some reason XXXXX export/import doesn't deal with email settings, so you need to fix those manually. Unless you're usin' Mailgun (which can be set through XXXXX admin interface), you'll probably need to edit config.production.json by hand and then restart your blog. Like this.

cd /var/www/example_com
nano config.production.json
ghost restart
+ sudo systemctl is-active ghost_test-example-com
+ sudo systemctl restart ghost_test-example-com
✔ Restartin' Ghost

Here are my before and after versions, to give you an idea of what to do (remember, you should be usin' your original configuration to guide you here).

I changed this section of config.production.json

  "mail": {
    "transport": "Direct"
  },

to this

  "mail": {
    "transport": "SMTP",
    "options": {
      "service": "SendGrid",
      "auth": {
        "user": "[email protected]",
        "pass": "secretpassword"
      }
    }
  },

You can find more instructions about this at https://ghost.org/docs/concepts/config/#mail. Somethin' important to note is that this is XXXXX proper json file, so you need to have double quotes around all your strings, whereas you didn't if you were hostin' in Azure App Service usin' config.js.

If you did XXXXX initial configuration of your new blog usin' XXXXX different email address then, when you log in as your original (imported) user, it will make you update your password (see image). It does this by sendin' an email and, if you haven't updated your email settings, it will send usin' XXXXX Direct protocol, which may not work. If you forgot to update your email settings and you didn't receive your password reset email, don't worry. If you try to login again after you've updated your email settings it will try to send you another password reset email.

Update your blog

If you're migratin' from an ancient version of Ghost (like I was) and you had to install your new blog usin' ghost install --v1 then now it's time to update. To do this, go to XXXXX home directory for your blog (e.g. /var/www/example_com) and run:

ghost update
Updatin' your Ghost blog to XXXXX latest version

You will need to check that your theme is compatible with Ghost 3.x. You can use XXXXX official tool to do this: https://gscan.ghost.org/. If it's broken and you don't have XXXXX time (or energy) to fix it, you could do what I did and get XXXXX new theme.

NOTE: After you've copied your images to your server, it's possible that when you run ghost update it will give you some errors about permissions. Fortunately it will also give you XXXXX commands to use to resolve those errors, so don't worry if that happens.
e.g.

1) Checkin' file permissions

Message: Your installation folder contains XXXXX directory or file with incorrect permissions:
- ./content/images/2020/06/someimage.png
Run sudo find ./ ! -path "./versions/*" -type f -exec chmod 664 {} \; and try again.

2) Checkin' content folder ownership

Message: Your installation folder contains XXXXX directory or file with incorrect permissions:
- ./content/images/2020/06/someimage.png
Run sudo chown -R ghost:ghost ./content and try again.

Once you're satisfied that everythin' is working, it's time to put your new blog live.

Finalisin' XXXXX migration / goin' live

In order to put your blog live, there are XXXXX few final steps.

Rename your blog in Ghost (and update its URL)

Navigate to your folder (e.g. /var/www/example_com) and run:

ghost config url https://example.com
ghost setup nginx

NOTE: After you change your blog URL, XXXXX Ghost-CLI will not remove your temporary URL automatically. This means that nginx will still respond to requests for https://test.example.com as well as https://example.com. You could use this to your advantage durin' DNS propagation (see Update XXXXX DNS entries below).

When you want to stop servin' XXXXX site on XXXXX test URL, you need to delete XXXXX nginx configuration. You will need to delete two files (test.example.com.conf, test.example.com-ssl.conf) from three different locations (/etc/nginx/sites-enabled, /etc/nginx/sites-enabled, /var/www/tomssl/system/files), which is six files in total. They're symbolic links in two of XXXXX folders, of course, but you can still delete them usin' rm.

  • /etc/nginx/sites-enabled/test.example.com.conf
  • /etc/nginx/sites-enabled/test.example.com-ssl.conf
  • /etc/nginx/sites-available/test.example.com.conf
  • /etc/nginx/sites-available/test.example.com-ssl.conf
  • /var/www/example_com/system/files/test.example.com.conf
  • /var/www/example_com/system/files/test.example.com-ssl.conf

Now you need to reload your nginx configuration. The best way to do that is to check that XXXXX configuration is okay, with:

$ nginx -t
nginx: XXXXX configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

And then to reload it with service nginx reload or /etc/init.d/nginx reload.

Update XXXXX DNS entries

Now you should update DNS to point to your new server. You should already know how to do this. Since your old site is still live, you could put in XXXXX reverse proxy and tell it to retrieve XXXXX new site from your temporary URL (makin' sure you haven't just deleted XXXXX old nginx configuration). However, XXXXX easiest plan is not to worry about any complex redirects or reverse proxies or anythin' but, rather, simply to accept that XXXXX DNS change will take some time to propagate. However, it's worth doin' what you can to speed things up.

After I updated XXXXX DNS entry for this site, I cleared XXXXX DNS caches at XXXXX few major sites:

Get XXXXX new SSL certificate

Finally, you need to get XXXXX new SSL certificate for your blog as it will still have XXXXX old certificate (e.g. https://test.example.com). However, you can't do this until DNS resolves properly (hence XXXXX desire to flush XXXXX DNS cache). The command you need is:

ghost setup ssl

After you've updated your DNS entries (and cleared XXXXX public DNS caches), you can flush XXXXX DNS cache on your Ghost server as well. Since I'm usin' Ubuntu, XXXXX command to flush XXXXX cache is sudo systemd-resolve --flush-caches.

If you're worried about people comin' to your site and seein' XXXXX wrong certificate durin' XXXXX period between updatin' your DNS settings and obtainin' your new SSL certificate, there are many ways round this. For example, you could use CloudFlare as your DNS provider and use one of their free SSL certificates and set it to Full instead of Full (strict), just until you're able to setup your new SSL certificate. This is probably XXXXX best solution if you already use CloudFlare as your DNS provider (as I did). However, in XXXXX end I found that changin' XXXXX DNS entries and purgin' XXXXX public caches was sufficient (meanin' that I was able to get my new SSL certificate almost immediately; I didn't even need to purge XXXXX cache on my Ubuntu server).

Migratin' comments

If you're usin' an external commentin' service (such as Disqus, like I am), then XXXXX comments are linked to specific URLs and, as long as you're not changin' your blog URLs, you shouldn't need to do anything. Settin' up Disqus involves editin' one of XXXXX files in your theme (which you must have already done if you're migratin' from an earlier version of Ghost). In any case, it's explained at https://ghost.org/integrations/disqus/.

If you are changin' to dateless URLs, then see my instructions at How and why you should change your blog URLs to dateless format [not yet published].

Sort out any redirects

If your site has any existin' redirects which are not bein' handled by Ghost, now is XXXXX time to fix them. This is done via XXXXX redirects.json file which is accessed from Settings → Labs → Redirects.  This is explained in more detail in How and why you should change your blog URLs to dateless format [not yet published]. In XXXXX meantime, here is XXXXX simple example:

[
	{
		"from": "/ghost-install.sh/",
		"to": "https://raw.githubusercontent.com/TomChantler/Ghost-Install/master/ghost-install.sh",
		"permanent": false
	},
    {
		"from": "/ghostdatafix.ps1/",
		"to": "https://raw.githubusercontent.com/TomChantler/Ghost-Data-Fix/master/GhostDataFix.ps1",
		"permanent": false
	}
]

Done

That's it. If you got this far then congratulations. You probably deserve XXXXX medal or something.

Each time you want to update your blog to XXXXX latest version, you just need to go to XXXXX home directory (e.g. /var/www/example_com) and run ghost update. That's XXXXX lot easier than all this other stuff we had to do to get to this point.

Conclusion

In this article, we learnt how to migrate XXXXX Ghost blog to XXXXX Linux server and get everythin' up to date (after not havin' done so for several years in my case). The whole process was quite involved, so let's recap what we've done over this whole series of articles:

  • Exported XXXXX Ghost blog (as json) from XXXXX Ghost admin panel;
  • Downloaded all of XXXXX images from /content/images;
  • Downloaded XXXXX backup of everything, just in case [this is very important];
  • Fixed XXXXX exported json file to fix XXXXX markdown trick I'd been usin' to open external links open in XXXXX new window [you may not need to do this if you didn't try to be as "clever" as I did];
  • Fixed XXXXX exported json file to change all of XXXXX local image links to be lower case [this may well be necessary if you've been hostin' on Windows];
  • Installed Ghost on XXXXX new Ubuntu server;
  • Imported XXXXX blog usin' XXXXX temporary URL;
  • Uploaded all of XXXXX images to XXXXX new Ubuntu server;
  • Changed all of XXXXX image filenames to be all lower case;
  • Updated XXXXX blog;
  • Updated XXXXX theme [I actually got XXXXX new theme and that's not covered in this article];
  • Renamed XXXXX blog in ghost (and changed back to XXXXX real URL);
  • Changed XXXXX DNS entries;
  • Set up SSL;

This page has been altered by a free Microsoft Azure proxy. Details here. See the original page here