Navigate back to the homepage

Setup Ghost Blog on AWS EC2 and RDS

Rommel Porras
August 2nd, 2019 · 6 min read

A full guide for installing, configuring and running Ghost on your AWS EC2 (AWS Free Tier) Ubuntu 18.04 server, for use in production.

Prerequisites

  • Ubuntu 18.04 EC2 image
  • NGINX (minimum of 1.9.5 for SSL)
  • Node Version Manager to install latest Node.js LTS version (currently at Node.js v10.16.0)
  • AWS RDS MySQL 5.7 or below (not >= 8.0)
  • Systemd
  • A server with at least 1GB memory
  • A registered domain name (ex: in Namecheap

Tip: Check the images for more detailed info in configuring EC2, RDS, NGINX, and SSL.


AWS EC2 Instance Configuration

I assume that you already have account on AWS / Amazon Web Services. There is an free tiers offer for new AWS customer. You can set up your account here.

The first thing we need to do is configure an EC2 instance. In case you’re not familiar to AWS EC2, Amazon Elastic Compute Cloud (Amazon EC2) is a web service that provides secure, resizable compute capacity in the cloud. It is designed to make web-scale cloud computing easier for developers.

Launch EC2 Instance

After you’d logged into AWS and you’re on the landing page, select the EC2 service. You will arrive at the EC2 Dashboard. Click that blue Launch Instance button.

AWS EC2 Dashboard

Choose an Amazon Machine Image (AMI)

First, you need to decide on the machine image you want.

You can choose this images for your Ghost project:

  • Ubuntu Server 18.04 LTS (HVM), SSD Volume Type
  • Ubuntu Server 16.04 LTS (HVM), SSD Volume Type instance.

We’re going to use the Ubuntu Server 18.04 LTS (HVM), SSD Volume Type instance, because Ubuntu 18.04 LTS is latest LTS version of Ubuntu and officially supported by Ghost.

AWS EC2 Amazon Machine Image AMI

Choose an Instance Type

We will pick our EC2 instance type, our server specs. You can use t2.micro type instance if you want to use your AWS Free Tier account and not getting bill for your dev/test server.

If you’re new in AWS and just trying it out, choose t2.micro. It has 1 GB of memory and 1 vCPU, the minimum required to run Ghost.

AWS EC2 Instance Type

EC2 Step 3 to 5

We will skip to detailed this out, because the use case of this is different from each users. If you want to see what I choose, see the images below.

AWS EC2 Configure Instance 1
AWS EC2 Configure Instance 2
AWS EC2 Add Storage
AWS EC2 Add Tags

Configure the Security Group

We will define what kind of connections we will allow to our instance. AWS will block everything by default, so you’ll need to enable the specific traffic you want to allow. In the default configuration, AWS will allow SSH over port 22 from your current IP address.

We will add public connection to our HTTP and HTTPS port from our security group, click Review and Launch button.

AWS EC2 Configure Security Group

Review Instance Configuration

Go ahead and review everything and make sure nothing sticks out as odd. Here’s my options:

  1. AMI is Ubuntu Server 18.04 LTS (HVM), SSD Volume Type
  2. Instance type is t2.micro for AWS Free Tier users (you can choose other instance type)
  3. Allowing SSH port 22 on your own IP address
  4. Allowing HTTP port 80 to the public
  5. Allowing HTTPS port 443 to the public
AWS EC2 Review Instance Launch

Key Pair Setup

When you click Launch button, AWS will show a popup asking you to either select an existing key pair, or create a new one. Create a new one if needed, download the key, and click Launch Instances.

Make sure to don’t lose the .pem keys, you need this to SSH in your EC2 instance. Wait for a few minutes, your EC2 instance will get ready.

AWS EC2 - Setup EC2 Key Pair

Setup AWS RDS MySQL 5.7

Create a AWS RDS database using MySQL 5.7 engine. Launch Ghost database using AWS RDS MySQL 5.7

AWS RDS Create MySQL 5.7 database 1
AWS RDS - Select RDS MySQL engine

Create RDS Use Case & Specify DB Details

If you are using this in your AWS Free Tier account, choose Dev/Test - MySQL, else choose others for your production environment Ghost project.

AWS RDS Create Use Case

*Be careful in choosing DB Instance class, other options have costing and not covered in AWS Free Tier.

AWS RDS Specify DB Details 1
AWS RDS Specify DB Details 2
AWS RDS Specify DB Details 3

Configure Advance Settings

AWS RDS Configure Advance Settings 1
AWS RDS Configure Advance Settings 2
AWS RDS Configure Advance Settings 3

Make sure to select Yes in Public accessibility, so our EC2 instance can connect to it. If you are not familiar in configuring AWS RDS, you can check my selected options so you can have an idea in what to choose.

Click Create database button to finish configuring AWS RDS.

AWS RDS Created AWS RDS MySQL

Wait for few minutes for your database to get ready.

Setup RDS’s Security Group for EC2 connection

AWS RDS Configure Advance Settings 1
AWS RDS Configure Advance Settings 2
AWS RDS Configure Advance Settings 3
AWS RDS Configure Advance Settings 3
  • Click RDS’s VPC security group under Security column.
  • Edit Inbound rules.
  • Add type MySQL/Aurora, TCP protocol, port 3306, source WebDMZ (that we create in EC2 instance installation step).

WebDMZ is the security group of our EC2 instance, we need this so our EC2 instance can connect to our RDS MySQL. Get the RDS endpoint in “Connectivity & security” tab of RDS.

Congratulation! We are finish in configuring AWS RDS MySQL database for our Ghost project.


SSH to EC2 Instance

Before getting started you should set an A record from the domain (ex: Namecheap) you plan to use, pointing at the EC2 server’s IP address and ensure that it’s resolving correctly. This must be done in advance so that SSL can be properly configured during setup.

AWS EC2 - SSH to your EC2 instance 1
AWS EC2 - SSH to your EC2 instance 2

To connect to our instance, we need to SSH to it.

1cd <directory-of-your-pem-key>
2sudo chmod 400 ghost-publishing-platform-cms.pem
3ssh -i "ghost-publishing-platform-cms.pem" ubuntu@ec2-3-112-67-64.ap-northeast-1.compute.amazonaws.com

You should be prompted on whether or not you want to continue, as the authenticity of the host cannot be established. Continue through this and you should successfully access your EC2 instance:

1ubuntu@<ec2-instance-public-ip>:~$

Installing Ghost in AWS EC2 Ubuntu image

First, we will need to establish all the prerequisites for installing Ghost-CLI, Ghost’s command line interface tool. Using the command line, setup a new user and log in as the created user (note: everything after # is a comment and should not be included in the command):

1ubuntu:~$ sudo adduser ghost-cms # add new user
2ubuntu:~$ sudo usermod -aG sudo ghost-cms # give new user elevated permissions
3ubuntu:~$ su - ghost-cms # login as new user
4ghost-cms:~$

Next, update the package list and upgrade the install packages:

1ghost-cms:~$ sudo apt-get update && sudo apt-get upgrade

Install NGINX:

1ghost-cms:~$ sudo apt-get install nginx
2ghost-cms:~$ sudo ufw allow 'Nginx Full'

Install NVM for Node.js

Next, we will install NVM so we can easily change our Node.js version in the future. “exit” to ghost-cms to fully activate the command of NVM

1ghost-cms:~$ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
2ghost-cms:~$ exit
3
4ubuntu:~$ su - ghost-cms
5ghost-cms:~$ command -v nvm

Install Node.js latest LTS (v10.16.0 at moment) and Ghost CLI

1ghost-cms:~$ nvm install --lts
2ghost-cms:~$ node -v
3ghost-cms:~$ npm i -g ghost-cli

And then verify it installed correctly:

1ghost-cms:~$ ghost help

Now create a new folder for Ghost to reside, give your ghost-user ownership of this direction, give the folder the correct permissions, and navigate to the folder:

1ghost-cms:~$ sudo mkdir -p /var/www/ghost
2ghost-cms:~$ sudo chown ghost-cms:ghost-cms /var/www/ghost
3ghost-cms:~$ sudo chmod 775 /var/www/ghost
4ghost-cms:~$ cd /var/www/ghost
5ghost-cms:/var/www/ghost$

Run the Ghost install process

1ghost-cms:/var/www/ghost$ ghost install \
2--db=mysql \
3--dbhost=ghost-blog.c5ll9wq6fpis.ap-northeast-1.rds.amazonaws.com \
4--dbuser=ghost_blog \
5--dbpass=unEEQR2fPVxfu3- \
6--dbname=ghost_blog
1? Enter your blog URL: https://<WITHOUT-WWW-paste-your-public-dns-here>
2? Do you wish to set up Nginx? Yes
3? Do you wish to set up SSL? Yes
4? Enter your email (For SSL Certificate)? ghostcmsblog@rommelporras.com
5? Do you wish to set up Systemd? Yes
6? Do you want to start Ghost? Yes

Enter the “https” link of your blog if you already link this to your DNS (ex: NameCheap)

Guides - Commands that I use in installing Ghost

Ghost CMS Blog Installation 1
Ghost CMS Blog Installation 2
Ghost CMS Blog Installation 3
Ghost CMS Blog Installation 4

Configure NGINX SSL - https:// (SSL) -> www

One of the cool things about Ghost is that it has its own CLI, which makes installing free SSL certificates from Let’s Encrypt even more of a breeze than using a tool like certbot. This is amazingly easy to use if you just plan on using a single domain:

1ghost config url https://<your-domain-without-www>.com
2ghost setup nginx ssl

Now let’s say you want to redirect http://example.com to https://www.example.com - if you have the knowledge to host your own Apache / Nginx web server, then doing that is pretty straightforward (using a rewrite rule). However, trying to redirect https://example.com to the www equivalent results in a big red certificate error. Why? Because your web browser tries to validate the certifcate before processing the redirect. Therefore, you need to have a valid SSL certificate for both your non-www and your www domains.

Normally this task is easily handled by fetching a certificate with multiple domain names (also sometimes referred to as a UCC certificate). However, because of the way Ghost handles SEO requests (the proper way), it technically only supports one domain.

Therefore, in order to redirect all non-www versions of your site to the SSL side, you first need to “trick” ghost by temporarily changing the site url (via Ghost knowledgebase).

Since this article setup Ghost on AWS EC2, you should change to the ghost-cms user:

1su - ghost-cms

Now change over to your ghost directory. ex: “cd /path/to/your/ghost/install”

1cd /var/www/ghost

Temporarily tell ghost to use your non-www url

1ghost config url https://example.com

Now tell Ghost to generate an SSL config for the non-www url

1ghost setup nginx ssl

Now change ghost back to the ‘primary url’ for your site

1ghost config url https://www.example.com

Now tell Ghost to generate an SSL config for the www url

1ghost setup nginx ssl

But you’re not done yet! Now you have to tell Nginx to redirect your site. Navigate to /etc/nginx/sites/sites-enabled (these are symbolic links so you shouldn’t have to hunt for your config files). Locate the non-www, non-SSL config file e.g. example.com.conf and open it using your editor of choice.

Next, add the following line at the bottom of the location section:

1location / {
2a bunch of stuff you should ignore
3return 301 https://www.your-primary-domain.com$request_uri;
4}
Nginx SSL 301 redirect

Don’t do this for files with “-ssl.conf”

Save and close the file, and repeat this task for example.com-ssl.conf and www.example.com.conf, but do not do this for www.example.com-ssl.conf and example.com-ssl.conf.

Now do this again your www conf file. DON’T apply the 301 redirect code to your config files with “-ssl.conf” extension.

1location / {
2return 301 https://www.your-primary-domain.com$request_uri;
3}

Restart NGINX After Applying 301 redirect code

1ghost-cms:~$ sudo systemctl restart nginx
2ghost-cms:~$ sudo service nginx restart

Nginx SSL Configuration Setup Commands

Nginx SSL Configuration for Ghost 1
Nginx SSL Configuration for Ghost 2

To summarize, what we just did was set up a 301 redirect for each domain that doesn’t match the https version of your primary one. Now, whenever a visitor browses to http://example.com, http://www.example.com or https://example.com, they’ll be redirected to https://www.example.com instead.

Nginx SSL Configuration for Ghost 2

Congratulations! You successfully host your Ghost blog in AWS. Go ahead and paste the URL you copied earlier into your favorite web browser and admire your handy work!

Happy blogging! <3


Join our email list and get notified about new content

Be the first to receive our latest content with the ability to opt-out at anytime. We promise to not spam your inbox or share your email with any third parties.

More articles from DevOps Cycle

DevOps Importance and Benefits?

DevOps—the amalgamation of development (Dev) and operations (Ops) teams—is an organizational approach that enables faster development of applications and easier maintenance of existing deployments.

December 1st, 2019 · 6 min read

Ghost Gatsby on Netlify - JAMStack

Want to serve your blog for FREE? Host your website for FREE in Netlify using Ghost headless CMS and Gatsby JAMStack starter pack.

October 27th, 2019 · 1 min read
© 2019 DevOps Cycle
Link to $https://twitter.com/devopscycleLink to $https://facebook.com/devopscycleLink to $https://github.com/rommelporrasLink to $https://m.do.co/c/1ba0ac3af2f6