Setup Ghost blog on AWS Lightsail

In this article we are going to talk about how to set up Ghost blog on AWS Lightsail. Ghost is professional publishing platform for building and running modern publications. You might be wondering why do we need to create our own when services like Ghost Pro and are already there? I am going to show you how you can get your blog up and running with very little effort and knowledge and save $$$. We are going to create blog "" in this article exactly the way I set up my blog originally. This is step-by-step guide to make ghost blog up and running with following is the architecture with self hosted ghost blog.

Full architecture on AWS
Outcome of this article

AWS Account Setup

First things first you need to have AWS account by using following instructions:

  • Singup for AWS account, or signup using this link
  • Enable multifactor authenticaion for you root account (optional but good for account security).
  • Creat administrator account for managment AWS infrastructure for example xalitech-admin, note down the account url for this user.
  • For security reasons, don't ever use your root AWS account for doing anything other than creating administartor account.
  • Now sign-out of root account and login with "xalitech-admin".

Create Lightsail resources

Go to Lightsail from AWS console, and click on instances and hit create instance button.

Lighsail home
Lightsail home - instances
Lightsail Operating System selection
Lightsail OS Selection

Now click on Networking tab, create static IP and attached to the instance you just created.

Create static IP
Create static IP

If you have done everything correctly you instance should look like following. Click on name of instance and go to networking tab and in firewall section allow https port 443.

Lightsail machine instance
Lightsail machine instance

Click on databases tab and create one with MySQL (5.x)

Select MySQL 5.x Database
Select MySQL 5.x Database

Your database instance should look like following.

Database creation
Database creation

You can enable public access to this db and check the connection to database using MySQL Workbench, but once everything is configured you should turn-off the public access to this database.

Setup Domain ""

Now you need to set up your domain because "" is already taken :) You have two options register new domain with AWS Route 53 or some third arty domains such as Google Domains or GoDaddy etc.

Route 53 Domains:

Look for good domain name suiting your blog and register with route 53. After registration, you should have domain and hosted zone. The only thing you need to do here is to create entry in your DNS Zone file for static IP you created for your Lightsail machine instance. Your DNS should look like following (mocked my private information):

Route 53 domain - DNS Zone
Route 53 domain - DNS Zone

For Google Domains or any third party domain providers

If you are not using Route 53 domain then steps are little different. Go to your Lightsail home and click on Networking tab and create DNS Zone. On zone creation screen you will be asked for the domain name you have registered with your provider and that wizard shows DNS servers for that zone.


Go to your provider and point domain names to these servers. This change might  take several hours to propagate, in my case I checked after 4 hours and it was done.

Once that is done come back to your Lightsail DNS zone and add "A" record pointing to your Lightsail static IP.

Install and Configure Ghost

Now everything is configured property let start what I promised.

Prepare Lightsail Ubuntu instance for ghost installation

Connect to Ubuntu instance via ssh (or in browser ssh) however you want, and execute the scripts in order.

# 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'
Note: Type your domain name "" in the browser  it should show welcome to Nginx page. If it does then you are good to proceed further, if don't please double check the steps earlier or give enough time to your DNS change propagation.

Now install NodeJS and Ghost CLI

# Add the NodeSource APT repository for Node 10
curl -sL | sudo -E bash

# Install Node.js
sudo apt-get install -y nodejs

sudo npm install ghost-cli@latest -g

Install Ghost

Now install ghost, you will be promoted for several things during the installation just type 'Y' for everything, specially "SSL" question. This will setup free SSL certificate from Letsencrypt.

# We'll name ours 'ghost' in this example; you can use whatever you want
sudo mkdir -p /var/www/ghost

# Replace <user> with the name of your user who will own this directory
sudo chown <user>:<user> /var/www/ghost

# Set the correct permissions
sudo chmod 775 /var/www/ghost

# Then navigate into it
cd /var/www/ghost

ghost install --url="" --db="mysql" --dbhost="(you-light-sali-instance-host)"  --dbpass="( get from light-sail instance)" --dbuser="(get from ligh-sali instance)" --dbname="(however you want to name db)" --dbport="3306"   --mail="Direct";

At this point you should see log message saying Ghost is running on "", you can further read about Ghost in the documentation. Until this point your blog is up and running, the next sections are optimization & scaling steps and completely optional.

Ghost Content as CDN using CloudFront and S3

Ghost has excellent support for verity of storage providers, in this section we are going to integrate ghost-storage-adapter-s3. Use the following steps in order.

  • Create new IAM user in AWS console for example "bucket-user".
  • Grand "bucket-user" permissions to manage S3 bucket.
  • Create S3 bucket, and updated policy as per documentation of "ghost-storage-adapter".
  • Create Cloud Front Distribution and put origin as S3 bucket you created above and leave the other default options as it is.

Now at this point your CloudFront CDN is set up you can use its URL in storage provider configuration "assetHost" or you want to customize it to something like "" follow the next section otherwise skip.

  • Once distribution is created and ready, go to edit mode and put look "Alternate Domain Name (CNAMEs)" and put
  • Update your Rout 53 zone file and add "A" type record with ARN of ClouldFront distribution, in value field.
  • Now this will ask you to request custom SSL certificates using ACM, put the domain name as "*" and request public certificate.
  • If the domain is registered with Route 53, this will ask you to add certificate request entries to your DNS zone file, go ahead and add.
  • On your certificate is ready, you can select from list of certificates from CloudFront edit wizard.

Follow the  storage adapter documentation for configuring S3 with Ghost and use "bucket-user" keys; as per documentation now your asset host should be "".

One thing is missing in the documentation, once you copy the adapter files to "./content/adapters/storage/s3" you need to go into this folder and run "npm install" to properly download adapter dependencies.

To test everything create sample post and upload image, you should see the image in S3 bucket.


Ghost is amazing blogging platform focused on publishing and search engine optimization (SEO), light weight on computing resources. Ghost offers significant advantages over other blogging platforms such as WordPress. Using Ghost on Lightsail is simple and easily scalable solution, you can create snapshot and spin up new instances within short time. There are number of blogging services that offers subscriptions such as Ghost Pro and but I feel if you know little about technology you should not be using those you can easily configure your blog on your own infrastructure which can be easily scaled up or down as per blog traffic.

I made number of decisions while configuring my blog, these include which Email service to choose, why use S3 buckets instead of local file storage, Lightsail over EC2, why Ghost over WordPress and event why AWS over Azure? I will cover each one in the following posts, plus many more tips to get more traffic for your newly created blogs, so stay tuned!

This was my first ever blog post written on anything, please share this post of you like it, feedback and comments are highly appreciated, thanks for sticking with me!