How to set up Ghost on AWS

The purpose of this post is to detail hot to set up the Ghost publishing platform on an AWS EC2 instance. The set up include how to configure your own domain running on SSL. The setup will cost you bewtween $0.50-$1.00 per day which is similar to the lowest on-premise plan but won't have the traffic and users restrictions.

Configuring the EC2 instance

The fastest way to install it is by using the Ghost Certified by Bitnami from the AWS Marketplace. Using this you will have an instance up and running with 3 simple clicks. The recommended instance is a t3a.small which is far enough for running Ghost with a cost of $0.019/hour.

Once the instance is up and running you can connect through SSH using the public IP.

ssh -i /path/to/pem bitnami@instance-public-ip

Then run the following command for getting the Ghost Admin credentials

cat ./bitnami_credentials

Now you can visit http://instance-public-ip/ghost. Congratulations your Ghost instance is working!

Configuring your own domain

Here you have two options depending on your own preferences. Configure your own domain with SSL (HTTPS) or continue with the simplest configuration (HTTP only). Nowadays, it's preferred to use SSL since Google is penalizing websites without proper certificates.

Simple configuration without HTTPS

The simplest configuration consists of assigning and static IP to your EC2 instance and then point your domain to it. The steps are quite simple.

  • Go to the AWS EC2 Console
  • Go to "Network & Security -> Elastic IPs" in the left navigation bar
  • And "Allocate New Address"
  • Now that you allocated a new static IP (Elastic IP address on AWS), you just need to assign it to your instance
  • Then go to your domain provider and add an A record pointing to the new static IP, you can add also a CNAME named www pointing to your-domain.com. Depending of your provider the DNS change will take up to 48h, you can verify the DNS records by using the Global DNS Propagation Checker and entering your domain name into the search field
  • Once DNS are propagated and your domain loads the Ghost platform, we have to configure it to use the new domain as the default URL. Login to your server using SSH and run:
cd /opt/bitnami/apps/ghost
sudo ./bnconfig --machine_hostname my-domain.com

Configuration using HTTPS

So, you understand that HTTPS is important and you want to configure your domain the hard way. To do so we will need to configure 3 extra AWS services.

  • ACM to issue the certificates
  • ELB to handle requests using SSL
  • Route53 as a DNS provider

Coming soon!

Remove port from your domain

In some cases, Ghost application keeps adding the port to URL, this is easy to remove, edit the file /opt/bitnami/apps/ghost/htdocs/config.production.json

The file should contain something like:

"url": "http://your-domain.com:80",
"server": {
	"port": 2368,
	"host": "127.0.0.1"
},
...

Remove the ":80" from the URL and restart Ghost with:

sudo /opt/bitnami/ctlscript.sh restart

Redirect www to root

If you added a CNAME www to your DNS configuration you will end with duplicated URLs and this is not recommended. A possible solution is to redirect www to the root domain.

Edit the file /opt/bitnami/apps/ghost/conf/httpd-vhosts.conf and add the following rewrite excerpts

<VirtualHost *:80>
	...
	RewriteEngine On
	RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
	RewriteRule ^(.*)$ http://%1$1 [R=permanent,L]
	...

<VirtualHost *:443>
	...
	RewriteEngine On
	RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
	RewriteRule ^(.*)$ http://%1$1 [R=permanent,L]
	...

And then restart the Apache service

sudo /opt/bitnami/ctlscript.sh restart apache

To check that everything is working as expected run the following

$ curl -IL www.notadatascientist.com

HTTP/1.1 301 Moved Permanently
Date: Mon, 13 Apr 2020 12:29:47 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Server: Apache
X-Frame-Options: SAMEORIGIN
Location: http://notadatascientist.com/

HTTP/2 200 
date: Mon, 13 Apr 2020 12:29:48 GMT
content-type: text/html; charset=utf-8
server: Apache
x-frame-options: SAMEORIGIN
cache-control: max-age=0, no-cache

As you can see there is a redirection from www to non-www

Redirect http to https

If you have your domain configured to use a certificate and your website is working well with SSL, it would be recommendable to force it. A possible solution would be to redirect http to https.

Edit the file /opt/bitnami/apps/ghost/conf/httpd-prefix.conf and add

SetEnvIf x-forwarded-proto https HTTPS=on

Edit the file /opt/bitnami/apps/ghost/conf/httpd-vhosts.conf and add the following rewrite excerpt

<VirtualHost *:80>
	...
	RewriteEngine On
	RewriteCond %{HTTP:X-Forwarded-Proto} !https
	RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
	...

And then restart the Apache service

sudo /opt/bitnami/ctlscript.sh restart apache

To check that everything is working as expected run the following

$ curl -IL http://notadatascientist.com

HTTP/1.1 302 Found
Date: Mon, 13 Apr 2020 12:34:04 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Server: Apache
X-Frame-Options: SAMEORIGIN
Location: https://notadatascientist.com/

HTTP/2 200 
date: Mon, 13 Apr 2020 12:34:05 GMT
content-type: text/html; charset=utf-8
server: Apache
x-frame-options: SAMEORIGIN
cache-control: max-age=0, no-cache

As you can see there is a redirection from http to https