Deploying Ghost on EC2

The following instructions pertain to getting a Ghost blog up and running using Ubuntu 16.04 on an EC2 instance. I figured since I'm using Ghost to run my blog that it would be a good first post to write! Setting up Ghost can be a bit tricky if you want to self-host and set everything up yourself.

Note: This post assumes you already know how to provision an EC2 instance and know how to SSH into it.

I'm using AWS's free tier so I can host my blog for free (for a year). In order to do that I am using an Ubuntu 16.04 AMI. For my security group I have the following ports open:

  • HTTP - Port 80
  • HTTPS - Port 443
  • SSH - Port 22

Associate an Elastic IP Address

In AWS an Elastic IP address is just a static IPv4 address. Heads up:

To ensure efficient use of Elastic IP addresses, we impose a small hourly charge if an Elastic IP address is not associated with a running instance, or if it is associated with a stopped instance or an unattached network interface.

In other words don't have an Elastic IP allocated if it is not associated with a running EC2 instance.

Assign a static ip to your new instance

In the AWS Console go to Elastic IPs under the EC2 service and allocate a new address. Once created click on your new Elastic IP then Actions -> Associate address. For resource type select "Instance" and then proceed to select the instance you want to associate with it.

At this point you should be ready to SSH into your newly created Ubuntu instance.

Creating a Ghost user

One of the first things you'll want to do after provisioning a new instance is creating a new user. It's usually good practice to set up an alternative user account with a reduced scope.

Switch to root and add a new user:

sudo su  
adduser ghost  

Enter a password when prompted and use the default settings for all other prompts if you desire.

Add Root Privileges

A lot of commands require sudo so we will make the new user a "superuser". This will keep us from having to use the root account. The requires adding the new "ghost" user to the "sudo" group.

Again as root run the following command:

usermod -aG sudo ghost  

You can now switch to the new user:

su - ghost  

Update your system

sudo apt-get update -y  

Install Node.js

We will install Node using a PPA (personal package archive) so we can get a more recent version of Node.js. Install the PPA:

curl -sL -o  
sudo bash  

After running the setup script from nodesource, you can install the Node.js package in the same way that you did above:

sudo apt-get install nodejs  

In order for some npm packages to work (such as those that require compiling code from source), you will need to install the build-essential package as well:

sudo apt-get install build-essential -y  

You may want to check your node and npm version to make sure everything installed correctly:

node -v && npm -v  

Installing Ghost

Grab the latest version using curl:

curl -L -o  

Create a directory for Ghost:

sudo mkdir -p /var/www/ghost/  

Install unzip and use it to unzip the files into the new directory:

sudo apt install unzip  
sudo unzip -d /var/www/ghost/  
cd /var/www/ghost/  

Install all Ghost dependencies by running:

sudo npm install --production  

Configuring Ghost

Ghost comes by default with a file called config.example.js. This contains everything Ghost needs to configure our blog correctly. We need to make a copy of this file and name it config.js. All of our changes will be made in this newly created config.js file. Note: We can leave the original copy in place in case we need to refer to it at a later time.

sudo cp config.example.js config.js  
sudo vim config.js  

Using vim or another text editor that can be installed on Ubuntu, edit the config.js file as described below.


Under the section that says "production" change

url: '',  


url: 'http://your-domian-or-elastic-ip-address',  

Ghost is configured by default to listen on port 2368. We need to change the config.js file to listen on port 80 which is the HTTP port. Change

server: {  
            host: '',
            port: '2368'


server: {  
            host: '',
            port: '80'

In the config file there is a section where you can setup your email information. I'm going to skip this for now but Ghost highly recommends setting it up. You can find more details on setting up your email client here:

At the moment, the only thing Ghost uses email for is sending you an email with a new password if you forget yours. It’s not much, but don’t underestimate how useful that feature is if you ever happen to need it.

Start Ghost

If you configured everything properly you should be able to start Ghost!

sudo npm start --production  

You are almost done at this point! In order for your Ghost blog to always keep running you will have to make it run as a service. Please check my article on Making Ghost Run Forever.

Chris Longe

Veteran DJ/Producer (in hiatus) • Computer Engineering graduate from UT Austin • Software Engineer at @CapitalOne • The revolution will be #swiftlang!

Washington D.C.