Ghost on Elastic Beanstalk pt. 2

Code Mar 13, 2016

Last Updated March 13, 2016: This is part two of a two part post on deploying Ghost to Elastic Beanstalk end to end. Click here for part one.

Part Two - Getting Ghost Ready for Users

Hopefully you have followed along part one of my guide. If you did, you should already be production ready. Now it's time to be user-ready, i.e. securing your blog, setting up a pretty domain, and set up continuous deployment.

To recap from the last post, here is the run down of what we're going to cover in part two.

  1. Associate a domain name
  2. Integrate Mailgun
  3. Enable HTTPS
  4. Set up your continuous deployment pipeline
  5. Integrate a theme

Continue to take some notes

There were four variables that we did not fill out yet from part one. Those variables are:

  • URL

We are going to fill out the rest of these in this post.

Buy a Domain Name

It doesn't really matter where you buy your domain name from. Namecheap, GoDaddy, Google Domains, and Amazon 53 are some popular options.

I prefer and bought my domain through Namecheap so the rest of my post will use Namecheap as the example. The process should be very similar with the alternatives.

First off, create an account on Namecheap and purchase your domain name. This should be straightforward so I won't go into how that's done. Once you have completed your transaction and purchase, you'll be able to manage and view your domains on your Dashboard, go ahead click "manage" for the domain name you just purchased.

Your Elastic Beanstalk environment should already be available to users at a subdomain of It should have also set this up as your CNAME record as described here.

All you'll need to do is associate your domain name with this CNAME. On Namecheap, you can simply click "Advanced DNS" and add a new CNAME entry. If you want your site to point to www (which is a subdomain of your domain name), you'll have to register your host as www. Otherwise, you can simply put @ as your host.

Note: If you associate your CNAME with the www subdomain, you'll also need to make sure that when a user types your domain name without the www, your site wil automatically redirect to your www subdomain. You can do that by setting up a redirect domain under the "Domain" tab of your console (an example is shown in the image further down).

Remember those remaining four values that we need to set up on our Elastic Beanstalk environment variables? Since we have our domain name set up, you can set the URL variable to your domain name!

If you followed these instructions correctly, you've successfully associated your blog to a domain name! Woo hoo! Give it a try! (may take a few minutes to work).

Integrate Mailgun

Mailgun is a transactional email API service and one of the ways you can configure your Ghost blog to send emails.

Thankfully the Ghost foundation has already documented the onboarding process for this, which you can follow along here. You can ignore the part where it tells you to modify your config.js because we should have already taken care of that in part one.

Instead, once you set up Mailgun, in your Elastic Beanstalk environment variables console, you'll want to set your SMTP_SERVICENAME as Mailgun and your SMTP_USERNAME and SMTP_PASSWORD as your Mailgun's default smtp login and default smtp password respectively.

After you follow all of these steps, your Namecheap console should look a little something like this:

Congrats! At this point, you should have had all your environment variables set up and you have completely made your Ghost blog user ready.

Enable HTTPS

This step is "optional", I use that term loosely because you should never skimp on security. Every site should run on HTTPS and a simple Googly Search will explain why.

If you want to enable HTTPS for your blog, simply purchase an SSL certificate (which you can do through Namecheap). If you purchase your SSL certificate through Namecheap, follow the instructions documented here on how to activate it. Your elastic beanstalk environment should be running on NGINX, so specify that as your Web Server when activating.

Once you activate and verify your certificate, you'll need to follow the steps documented on AWS to set up your certificate on your Elastic Beanstalk environment. These steps should be fairly straightforward but feel free to comment or let me know if you run into any issues here.

Note: Remember that once you enable HTTPS, you'll want all of your source URL's to redirect to HTTPS, you can do that by configuring your redirect domain again. It should look like the image below (except with your domain name of course).

Set up your continuous deployment pipeline

This step is also completely optional and has no implications. This is aimed for the pros out there who want to set up a continuous deployment pipeline with their blog. I will talk about the importance of this in a later post, but here's the TL;DR. If you want to keep your Ghost blog up to date with the latest releases, you'll have to manually push the latest release to your Elastic Beanstalk environment through the console or the CLI. Lets avoid that.

To set up continuous deployment, we are going to use a combination of Codeship and Git. You'll need to push your code to Bitbucket or Github. I have my ghost blog hosted on a private GIT repo on Bitbucket.

Why Bitbucket? Because it costs money to have private repos on Github (and I'm a cheap-ass) and because Codeship does not have support yet for Gitlab.

Why private? No particular reason. There should be no exposed sensitive data with my Ghost installation. The config.js file may be the only file that can expose sensitive information, but if you followed my steps in part one correctly, there should be nothing visible. But I have a principle of never making repos public if you don't intend for them to be be open-sourced. So feel free to use Github if you don't care or if you're a rich mothatrucka and can afford their private repos.

Push your Ghost repo to one of the Git solutions mentioned above. When that's done, you'll want to head over to Codeship and configure your project. The instructions can be found here.

Afterwards, set up your project to auto-deploy to Elastic Beanstalk environment by following the instructions here. Remember the codeship IAM user we created in part one? You'll want to use that here.

If you followed the instructions correctly, whenever you commit new code to your Ghost repo, Codeship will automatically build your project and deploy your code to Elastic Beanstalk! What?!?!? So easyyyyy.

Integrate a theme

This last step involves installing custom themes for your Ghost blog. Your Ghost blog should automatically come with Casper, but you probably want to make your blog unique and all that jazz. Unless you really like the default theme, then go nuts. You can discover new themes on their marketplace and install it by following these instructions here.

Shameless plug: The theme for this blog was built by me and you can find it on my Github.

If there's a theme that you really like or if there's a theme you've created that you're constantly updating, if the theme is hosted on a Git solution, you can continue to follow the continuous deployment practice by setting up your theme in your project as a Git submodule.

You can do this by creating a .gitmodules file at the root of your Ghost installation and create a reference to the theme like the example below:

[submodule "content/themes/caffeine-theme"]
	path = content/themes/caffeine-theme
	url =

Except the name of the theme and the GIT path will be different depending on the theme you prefer to use.

The great thing is that whenever there's a new update to the theme, your Ghost repo will automatically detect those commits. You can push your Ghost repo, with the new theme commits, and Codeship will automatically rebuild and redeploy the latest theme! In addition, because this is all done through Elastic Beanstalk, there is automatic rollback with zero downtime! Awww yisss.

Self-host vs. Pro Service

Damn that was a lot of work just to get this thing live. The Ghost foundation also provides a pro service where they'll do alllll of these things for you for a flat monthly fee.

So why did I self host? Well, for a variety of reasons. It was an opportunity to get more familiar with AWS and its services! In the era of cloud based hosting, it is definitely a strong skill to add to your repertoire. I can now manage all the infrastructure myself, it gave me the opportunity to go through all the steps of getting my site out to the world, and the continuous deployment pipeline was pretty sweet as well.

But, the pro service DOES handles all the infrastructure and I don't need to spend any time to do that. It also allows you to deploy themes easily and will auto update the Ghost platform so you never need to upgrade it yourself. Those pretty much remove the need for a continuous deployment pipeline... It's also cheaper at $20, whilst this AWS infrastructure costs me a pretty penny of about ~$50 a month... Getting my blog live in AWS also took me a couple of working sessions to nail down and run properly.....

.......damn it