The Biggest (Invisible) Change to Birchtree in 4 Years

Posted by Matt Birchler
— 6 min read

Back in 2019 I wrote The Biggest Change to Birchtree in 5 Years, which explained my move from WordPress to Ghost. 4 years later, I'm still very happy with Ghost, but I'd worked myself into a bit of a "thermal corner" if you will.

In short, my server was running Ubuntu 18.04 LTS, which was the best option back in 2019 (Ubuntu's naming scheme is "year dot month" so 18.04 released in April 2018), but time has passed, and I'm ashamed to admit I was not keeping up on OS updates, so I was still running that old version of Ubuntu. That wasn't really an issue until Ghost updates started to require versions of Node that didn't run on my old version of Ubuntu, so I was blocked from updating Ghost and getting new features. I tried doing the updates via the command line, but things kept breaking and I felt I wasn't getting anywhere.

My solution was:

  1. Spin up a new droplet (server) on DigitalOcean using Ubuntu 22.04 LTS and a fresh Ghost install
  2. Import my posts and media from the old server
  3. Update DNS to redirect traffic
  4. Deal with any weird side effects

Setting Up a New Droplet

DigitalOcean absolutely rules, and I continue to be a very happy customer of theirs. Creating a new droplet takes less than a minute, and they have a Ghost configuration you can choose, which basically means that after the droplet is set up, the first time you ssh into it, a script runs that will install Ghost and get your SSL set up for you.

For those who are curious, I use the $14/month plan for this blog, which is more than enough power most of the time, but saves my butt when someone big links to me and traffic spikes for a bit. Ad revenue from this site is typically around that same amount, so I'm effectively breaking even on the site (assuming we count my time as worth nothing 😛).

This isn't a Ghost tutorial, so I won't get too into the weeds here, but basically it took less than 5 minutes for me to have a new server on the web with a fresh Ghost instance set up. I set up my account password and moved onto the next phase.

Migrating Content

To export your site from Ghost, you can go to Settings > Labs and click the "Export you content" button. This will give you a JSON file with all of your posts and most other site settings. Critically, it does not contain your images or videos you've uploaded to your posts, so those will not be there, and all references to those photos in your posts will show errors by default. Don't worry, we can fix this.

On the new site, I went to the same Labs page and instead selected "Import content" which let me upload the JSON file I got from the old site. I have over 3,000 posts, so it took a few minutes, but about 10 minutes later I had all my posts imported into the new site.

Also worth noting that your theme does not come over in the export, so you need to install that again. I browsed through the theme marketplace to see if there was anything I thought I could just use, but nothing really worked for me (although I did buy Nova and really like it, but it doesn't quite work for me since it crops header images to a fixed aspect ratio which I don't like). Anyway, I downloaded my theme folder from my old server, zipped it, and uploaded it as a theme in the new site. Everything came over perfectly.

But then there were all the images I've uploaded over the years.

To get these files, you need to ssh into your old server, go to your Ghost install folder (likely in var/www/ghost/) and check the content/images/ directory for folders with all your images you've ever uploaded. You're going to want to download those and upload them into the same place in your new server. And yes, include the "size" directory, as that is where Ghost stores all the optimized versions of your images.

I've also uploaded a few videos over the years, so I also had a few files in the media directory, which I also moved over to the new server.

One more thing, make sure that you update permissions on these images and media directories to 777 so that Ghost can properly access those files and users can see them in their browser. This is not something you have to do normally, but I think the permissions got a bit wonky by downloading them to my Mac and then uploading from there.

And that's it! You should be able to go to any of my old posts and see images there just like normal.

Updating DNS

I really can't help you here, since every setup is different, but at a basic level, DNS is what tells someone who types "" into their web browser that it needs to send them to the IP address my server is hosted at. It also handles things like knowing that,, and should all go to the same place and correct the URL to

I own this domain through Hover and I'm using CloudFlare for DNS. On the Hover side, that means all I have to do is enter the nameservers CloudFlare told me to use (see below). This completely negates the need to do anything with DNS in Hover's interface, as CloudFlare is handling everything.

Now all I had to do was log into my CloudFlare account and add a new DNS A record for the new IP address.

The MX records are there for Gmail, they're unrelated to the blog, but I can use the domain for both

Thankfully, this conversion took seconds, and CloudFlare was properly redirecting my traffic to the new IP address basically instantly…a minor miracle compared to other times I've dealt with DNS changes other places.

Dealing with Problems

I always like to say I don't want to make any changes to this site that make my readers do any work or even notice anything behind the scenes has changed. The tools I use to publish should be of zero interest to you, and if you're subscribed, I consider it a failure if I need to ask you to subscribe again somewhere else.

This change did not require you to do anything at all. The domain stayed the same, all permalinks are the same, and my RSS feed is the same. If I wasn't writing this post, I would be most people wouldn't even notice anything has changed.

The one issue I ran into was the RSS feed, which sadly considered all this content new, and spit out 10 "new" articles to subscribers last night. This also impacted my Mastodon posting automation, which spammed your feeds with the last 10 posts again. My bad.

In retrospect, what I could have done to minimize the impact here would have been to go into my Feedpress settings and set the "Truncate entries number" to 1, which should have made it so only 1 post would have appeared as a duplicate. Well, live and learn.

Final Thoughts

At the end of the day, this wasn't the most exciting update in the world. At most you've noticed some duplicate posts in your RSS reader, and I simply completed a minor point release update to my Ghost back end, but this does give me a more stable, secure back end and ensures that Ghost updates will be easier to handle going forward. I will need to make sure I perform system updates more regularly this time so I don't have to do this same sort of migration in 2027. But if I do, hopefully I'll remember this post and it will go smoothly.