Hosting Ghost on AWS EC2 with SSL Enabled

Okay. So this is my fifth attempt at starting a blog. Each time I've started one in the past I'd come up with an inaugural "why" post. If the definition of insanity is doing the same and expecting different...well I should mix it up.

This time, my inaugural post will cover getting Ghost up and running on AWS EC2 with SSL for that https:// goodness. AKA what I went through to get up.

Before we jump in - there are awesome existing resources that will walk you through most of this already. In fact, this guide will mostly be a rehash of what Joshua Erney has laid out in his post here.

His post is pretty solid but I ran into two issues:

  • No SSL walk through
  • Few bugs related to MySQL & ghost-cli

Here's hoping this guide helps folks who ran into the issues I did.

EC2 Instance Config

Let's begin with the EC2 instance config. You need an Ubuntu 18.04 image on a T2 micro instance. You could go for a different instance type, but I chose T2 micro since it's free-tier eligible. #savedatmoney

Ubuntu 18.04 is recommended, but 16.04 works as well

For the Ubuntu version, as long as the version is supported by Ghost you're in the clear. This is liable to change over time, so feel free to go with the most recent supported version.

Before launching, make sure to configure the security group to allow:

  • HTTP
  • SSH

Make sure to give this security group a descriptive name & description. Then, launch!

When you launch you'll get a prompt to create a key-pair or use an existing key-pair for the instance. Go with either option - but make sure to save the key-pair (.pem file) locally on your computer somewhere safe. You won't be able to access your server through SSH if you don't have access to it.

For the sake of example, let's assume my key-pair file is called aadhi-blog.pem and it's hosted in my Documents folder. If you created a new key-pair, then make sure to change permissions on the file:

chmod 400 ~/Documents/aadhi-blog.pem

NOTE: For those who are curious, here's a list of chmod codes and what they mean.

Setup DNS

Next, we need to make sure our domain points to our newly minted EC2 instance. First, grab your instance's IP address:

Sample EC2 Instance Pane

Now, I used Namecheap as my domain registrar - but these steps should apply across all providers:

  • A Record with host "@" and value equal to your EC2 instance's IP address
  • URL Redirect Record with host "www" with a value equal to your domain name

In my case, the URL Redirect Record was host "www" and value equal to

The net here is that if someone types in:

  • then they'll redirect to my EC2 instance
  • then it will redirect them to which leads to my EC2 instance

Install Pre-Reqs

Ghost has a few pre-requisites. You'll need:

  • Non-Root User
  • Nginx
  • MySQL
  • NodeJS & NPM

Before that, you need to SSH into your instance. Grab the path to your .pem file from above. Once you have that, use the following command to remote into your instance:

cd ~/Documents
ssh -i aadhi-blog.pem ubuntu@

Non-Root User

Once you're in, create a non-root user, give that user root privs, and switch over to that user:

sudo adduser aadhi
sudo usermod -aG sudo aadhi
su - aadhi

Using a non-root user is a hard requirement for Ghost. Make sure not to skip this step.


Before we install Nginx, update & upgrade the install packages:

sudo apt-get update
sudo apt-get upgrade

Once update & upgrade finish, install Nginx:

sudo apt-get install nginx

You'll also need to adjust the Nginx firewall to allow HTTP(S) connections:

sudo ufw allow 'Nginx Full'


Okay, now it's MySQL time:

sudo apt-get install mysql-server

Once it's installed, you need to manually setup a user. This caught me initially since ghost-cli should do this. But, for some reason it always error'ed out for me.

Anyhoo, to setup a user:

sudo mysql
GRANT ALL PRIVILEGES ON *.* TO 'aadhi'@'localhost' IDENTIFIED BY 'examplepassword';

You can replace 'aadhi' and 'examplepassword' with whatever username /pass combo you want to use. Make sure to note both - you'll need it in a second.

NOTE: Here's a link to the source I used for creating new users in MySQL

NodeJS & NPM

Finally we're going to install NodeJS:

curl -sL | sudo -E bash

As of writing this post, the recommended version is 10.16.0. Over time that'll change, so just change "10.x" to whatever the current major version is and you're good to go.

After pulling the latest package, install it:

sudo apt-get install -y nodejs

Assuming everything went according to plan, you can check your install of NodeJS & NPM with:

  • node -v
  • npm -v

Ghost Installation

To install the ghost-cli use:

sudo npm -i -g ghost-cli@latest

The "@latest" decorator will pull the latest version, so it should stand the test of time. If you want to verify the install worked, then use:

ghost help

Next, we'll setup the web directory for NGINX. Do:

sudo mkdir -p /var/www/
sudo chown aadhi:aadhi /var/www/

NOTE: The "aadhi:aadhi" can be replaced by the non-root user you created towards the beginning of the guide.

Then change to the directory you just created and install ghost:

cd /var/www/
ghost install

You'll get prompted for a few options. Here's how you should navigate this part:

Enter your blog URL:
Enter your MySQL hostname: localhost
Enter your MySQL username: aadhi
Enter your MySQL password: examplepassword
Enter your Ghost database name: aadhi_rocks_prod (any name works)
Do you wish to setup NGINX: yes
Do you wish to setup SSL: yes (will prompt for email)
Do you wish to setup Systemd: yes
Do you want to start Ghost: yes

If everything worked, then the terminal should spit out:

Your admin interface is located at:

You can use that URL to get started on setting up your admin account in the friendly Ghost GUI.

If you have any comments / additions you'd like to make to the guide - feel free to DM me on Twitter. Happy blogging!

Show Comments

Get the latest posts delivered right to your inbox.