This blog runs on the Ghost blogging platform. I generally use WordPress, but I wanted to give this a try, as I've seen many other blogs effectively use this software. Not wanting to shell out $30 per month, I started self-hosting it on its own VPS at Vultr. That got me down to $5 per month. But I already have a solid VPS where I host many other domains, but it didn't support NodeJS.

Thus began my migration to Plesk. After several years using ServerPilot's free plan, I wanted something more self-hosted. At Vultr, I can spin up a Plesk instance for the price of the VPS, plus $7.50 per month for up to 30 domains. After migrating almost all my other sites to the new server, I began researching installing Ghost on Plesk. There just isn't that much documentation on how to do this. Fortunately, I stumbled upon a YouTube Video for installing an older version of Ghost. After much experimentation, it turned out to be a pretty straightforward process:

  • Enable Node and Phusion Passenger through Plesk's Updates and Upgrades
  • Make sure Apache Web Server Settings has "passenger" enabled
  • As root, install the runtime binaries: curl -sL https://deb.nodesource.com/setup_8.x| sudo -E bash -
  • Install NodeJS as root: apt install nodejs
  • In Plesk, add your domain and extract Ghost into that directory
  • Create a database for your blog
  • Edit: core/server/config/env/config.production.json for your database settings and add a line for the URL to your domain: "url": "https://example.com”,
  • With all of your source in place, use Plesk to start NodeJS for your domain:

With all that ready to go, click on NPM Install (to generate Node Modules), then Start (or Restart) App. That should do it! If I missed anything, please let me know.


As a side note, I also use Cloudflare. For some reason, this stops Scheduled Posts from posting. Ghost's API post mechanism doesn't pass through Cloudflare. As a workaround, I added my server's local IP address to my /etc/hosts file. Now when Ghost triggers a scheduled post, it hits the server directly and bypasses Cloudflare.