Easily Hosting a Ghost Blog on Google Cloud Compute Engine

Easily Hosting a Ghost Blog on Google Cloud Compute Engine

If you're considering using Ghost to run a personal blog, the best way learn about the platform is to try it out. Let's launch a Ghost blog hosted on the Google Cloud free-tier in under 45 minutes.

This deployment will let you serve an entire Ghost blog or just the API.

Before you copy and paste code, you can click on the text to replace the [PLACE_HOLDERS] with your inputs. Your inputs aren't saved.

Why Google Cloud?

You can comfortably host the Ghost CMS on Google Cloud Platform (GCP) for 1 year at no cost. That's assuming you haven't activated your free trial yet, which lasts 1 year or $300, whichever comes first. If you've never signed into GCP before, click here to log in with your Google account and activate your free trial.

Google also has an always free tier, but it's limited to the f1-micro instance which is just a little bit underpowered for smoothly running Ghost. I've done it and it's definitely better than nothing!

If you just want a plug and play solution and don't mind paying for it, here's a quick list of options.

Even within GCP there are many ways to deploy a Ghost blog. The following was the most simple and straightforward way I could find, and also how this blog is hosted!


You'll need these at the ready before we get started:

  1. A domain name. If you don't have one yet, I can recommend these services:
    a. Name.com
    b. Name Cheap
    c. Google Domains
  2. A Google account. If you've never logged into GCP with your account your free tier will be waiting for you. If you've used GCP in the past, you might not have any free credits remaining. I'll do my best to break down the costs of the services used in this tutorial.

Now let's launch a blog.

Part 1: An Economical Deployment

For a simple and cost effective solution we're going to deploy our blog by spinning up a single virtual machine (VM) in GCP Compute Engine that will serve the Ghost CMS and front end. Since the entire blog is served by one VM, you'll only pay to keep one compute instance running. You can increase the capacity of your compute instance whenever to accommodate more traffic.

1.1: Creating a New Project in GCP

Log in to GCP and navigate to your dashboard home (or get there by clicking here).

Click on the project menu located in the header and click "New Project" at the top right of the popup.

Enter a project name such as my-ghost-blog. Make sure to edit the project ID now since you won't be able to change it later.

Don't forget to change the project ID now!

Once the project is created, go back to your dashboard home and make sure you select the project in the project menu. You should see a dashboard like this with no resources and the correct ID for the project you just created:

Now let's add a compute engine resource to our project where we will run the VM.

1.2: Launching a VM in Compute Engine

These are the official recommendations from Ghost on how to set up our VM:

The officially recommended production installation requires the following stack:

  • Ubuntu 16.04 or Ubuntu 18.04
  • NGINX (minimum of 1.9.5 for SSL)
  • A supported version of Node.js
  • MySQL 5.5, 5.6, or 5.7 (not >= 8.0)
  • Systemd
  • A server with at least 1GB memory
  • A registered domain name

To go about installing all of those requirements, first we need to spin up a VM running Ubuntu 16.04.

Start by searching "add vm" in the search bar and select Add VM Instance.

It may take some time for the page to fully load as GCP sets up Compute Engine. Once the page is loaded select "New VM Instance" and configure as follows:

  • Name: Pick any name for your VM, such as ghost-vm
  • Region: Select either us-west1, us-central1, or us-east1. Only these regions are eligable for the always free tier.
  • Machine Type: Select n1-standard-1. We'll switch to the cheaper g1-small machine type once installation is over. We need some compute power to set Ghost up.
  • Boot Disk: Select Ubuntu 16.04 LTS and 30GB of persistant disk space.
  • Firewall: Allow both HTTPS and HTTP traffic for now. We can change this later when we configure security.
  • Leave everything else default or explore the options to customize your configuration. Lots of possibilities here.

Click "Create" to launch the VM. It will take a moment for your VM to launch.

Once it's launched, note down the VMs external IP. We'll use it to set up the domain name next.

Your VM is publicly reachable on the internet at the external IP.

1.3 Update Your Domain's DNS Records

To point your domain name to the VM's IP address, we need to add a DNS record to the domain name's name server. Log in to your registrar (where you purchased the domain) and navigate to the DNS settings for the domain you'll be using for Ghost.

First, make sure there are no A records with a blank, @, or * value for Name/Host record/Alias. If these records already exist delete them. Unless you're using them of course. If you're already using the root domain (`example.com`), you can use a subdomain like blog.example.com. If you plan on using the Ghost installation as a headless CMS, something like content.example.com makes for a good subdomain.

Find the option for adding a new DNS record. Add the following  A record:

  • Name/Host/Alias: @ if using the root domain. [SUBDOMAIN_NAME] if using your own subdomain.
  • Time to Live: (TTL): Leave default value or 3600 if no default.
  • Type: A
  • Value/Answer/Destination: [VM_EXTERNAL_IP]

Now all requests to your domain or subdomain will be directed to your VM. DNS changes typically take ~30 minutes to propagate but can take up to 24 hours (check the status here).

1.4: Installing the Stack on the VM

These are the remaining requirements for Ghost:

  • Ubuntu 16.04 or Ubuntu 18.04
  • NGINX (minimum of 1.9.5 for SSL)
  • A supported version of Node.js
  • MySQL 5.5, 5.6, or 5.7 (not >= 8.0)
  • Systemd
  • A server with at least 1GB memory
  • A registered domain name

We can add all of that to the VM with a few lines of code sent via the command line. First we need to access the VM command line by SSH-ing into it.

Navigate to your list of VM instances here. Connect to the VM via SSH with "SSH" > "Open in browser window". This will allow us to send commands over to the VM.

You should see a command line open up in a new tab like this:

Press enter to run a command.

First, let's create a new user named guser with the command sudo adduser guser. Choose a simple password. You can skip all of  the prompts by hitting enter for all of them. Hit y to confirm the info. Then run sudo usermod -aG sudo guser to grant privileges and finally su - guser to log in. Enter the password you chose for the user when prompted.

We're going to create a .sh file of command line code. We can execute the entire file like a program that will configure the VM and install Ghost in one fell swoop.

To create the file, run the command sudo nano ginstall.sh (you'll have to type your password one last time). This will create a file named ginstall.sh and open up the nano interface.

Paste this code into nano:

# Update package lists
sudo apt-get update
# Update installed packages
sudo apt-get upgrade
# Install NGINX
sudo apt-get install nginx
sudo ufw allow 'Nginx Full'
# Install MySQL
sudo apt-get install mysql-server
# Add the NodeSource APT repository for Node 10
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash
# Install Node.js
sudo apt-get install -y nodejs
# Install Ghost CLI
sudo npm install ghost-cli@latest -g
# Create a directory for Ghost
sudo mkdir -p /var/www/ghost
sudo chown guser:guser /var/www/ghost
sudo chmod 775 /var/www/ghost
cd /var/www/ghost
# Install ghost and let the user finish the program.
ghost install

Once pasted, hit control + x and press y when prompted to save the file. Then hit enter to exit nano.

Run sudo chmod +x ./ginstall.sh to give the script permissions. Then execute the script with ./ginstall.sh.

Enter y when prompted with a yes or no. MySQL will ask for a password, enter a password and make sure to note it down.

Lastly, Ghost will install and prompt you to set up your blog:

  1. Blog URL: https://example.com but use your blog's domain name
  2. MySQL host name: just press enter for the default value
  3. MySQL user name: enter root
  4. MySQL password: enter the password you gave when prompted by MySQL
  5. Ghost database name: enter for the default
  6. Set up "ghost" mysql user: Y for yes
  7. Set up Nginx: Y for yes
  8. Set up SSL: Y for yes
  9. Email for SSL: Enter your email to get a free SSL certificate from Let's Encrypt
  10. Set up Systemd: Y for yes
  11. Start Ghost: Y for yes
These are the prompts that ghost install will take you through.


Your Ghost blog is now up and running at your URL. Set up your site at example.com/ghost using your domain name. Be warned that anyone can create the first admin account by reaching example.com/ghost before you.

1.5: Set up an Email Service

Ghost can send emails to subscribers and use email for helpful administrative tasks like password reset. In order to enable email we need to set up an email service from a provider such as AWS SES, MailGun, or SendGrid – I recommend MailGun and SendGrid.

For this tutorial I'll use SendGrid because I can subscribe through GCP. The free tier allows for 12,000 emails per month indefinitely. Set up a SendGrid account and find your API console (here). Under Settings > API Keys create a new API key with mail send permission only and give it a legit name. I'm using ghost-test for demonstration purposes.

Copy the API key and store it in a safe place.

Now return to the VM's terminal. Use cd /var/www/ghost to make sure you're in the ghost directory. Then run these commands one by one to configure the email settings:

ghost config --mail SMTP

ghost config --mailservice Sendgrid

ghost config --mailuser apikey --mailpass [SENDGRID_API_KEY]

ghost config --mailhost smtp.sendgrid.net

ghost config --mailport 465

For the config changes to take effect, restart Ghost with ghost restart.

Navigate to Labs in the admin of Ghost (at the bottom of the left hand menu) and find Test email configuration. Run the test to make sure it's working.

1.6 Downgrade the Compute Instance

Installing Ghost required the n1-standard-1 compute resource, however; hosting the site casually can be done with the smaller and less costly g1-small instance. You can even downgrade to the always free f1-small instance, but it probably won't make a practical public website with so little compute resources.

First stop ghost by running ghost stop in the command line.

Now let's downgrade the compute engine we launched in step 1.2 to g1-small. Navigate to your list of VM instances here.

Click on the VM instance and press the Stop button up top. Once stopped, click Edit and change the instance type to g1-small. Restart the instance.

SSH back into the VM instance once it restarts. Log-in as guser with su guser. Then navigate to the ghost directory with cd /var/www/ghost. Start ghost back up with ghost start.

I've come accross a common issue with ghost where the port number can increment on reboot or restart from 2368 to 2369. If this happens you'll likely see a 502 error when you try to access the blog. I usually just reset the port number back to 2368 with the command ghost config port 2368.