You’re stupid if you don’t have a community. At least that’s what the internet keeps telling me.

I’ve been building products and businesses for a decade but I’ve never built a community. Newsletters/communities are valuable because that group follows you wherever you go. Beyond company and product, a loyal audience will reward you many times over (can sell many products to them, create paid content etc).

Over the coming months I’ll write about my attempt to build a paid community from nothing*. If you want, check out my progress at Grit List, my personal growth newsletter. I email you once a week on how to improve your life/self.

This article walks you through how to setup a Ghost blog from scratch on AWS, leveraging there new Membership and Newsletter features.

Now, let’s get started!

*Nothing defined: I currently post to social platforms once every 3 months. I have 642 followers on Twitter. I have a few hundred email addresses from a few products I’ve launched before, but I haven’t yet decided if I’ll use them. I also have 932 followers on Medium, from a series I did 2 years ago…and I haven’t posted in 2 years.


First step, what tool/medium should I use?

There are a lot of options; Wordpress, Ghost, Substack, and Medium to name a few. You can have a newsletter or a website or both. Options options.

Ultimately, I decided to go with Ghost. Ghost recently released their 3.0 version, which includes the ability to have and maintain members, charge membership fees, and send out newsletters. It’s basically the exact same thing as Substack, except that you are able to control everything yourself, i.e. more effort, more reward.

The best part? If you build it in Ghost then there’s $0 membership fees. While this post is focused setting up Ghost on AWS, you can also simply use Ghost Pro’s platform if you’re not technical and want to pay $36/mo.

Without further ado, I give you my guide on how to setup a Ghost Membership platform on AWS.


These are some things that I don’t go into, but are needed to complete this tutorial. Most of them are intuitive and straightforward, which is why I didn’t go into them:

  1. Have an AWS account (needed for hosting)
  2. Have a Stripe account (needed if you want to paid members)
  3. Have a custom domain (if you want to set up your custom domain)
  4. Some familiarity with command line (can work around this, but not covered in this tutorial)

Launching your Instance

To get started, signin/up to AWS and go to this AMI for Ghost. Click:

  1. “continue to subscribe”
  2. “continue to configuration”
  3. “continue to launch”
  4. If prompted to create a keypair, do it, and download it and save it as mysite-keypair.pem. We will use this later.

Here you can configure your EC2 Instance Type to be t2.micro instance, which is free for up to 750 hours per month. Free is good! Select that, and leave everything else the same, then click “Launch”.

Once your application finishes launching, you’ll need to get access to your your Ghost installation.

Getting Ghost admin access

  1. Go to AWS Cloud Console, and open Compute -> EC2
  2. Select your newly created Instance (under Instances)
  3. With your Instance checkbox selected, go to Actions>Instance Settings>Get System Log
  4. Scroll to the bottom and then slowly scroll up until you see a call out section starting with “Setting Bitnami application password…”
  5. Copy and save your Ghost admin username and password for later
  6. For more detailed steps, view Option 1 in this tutorial

Log into your Ghost installation

  1. Within AWS, copy and paste your Instance’s Public DNS. It should look like this:
    • Pasted_Image_6_9_20__10_05_AM
  2. Go to the URL of your public DNS to confirm your site is running
  3. Add /ghost to the end of your URL to view the Ghost Admin page (e.g.
  4. Log in with the username and password from the Getting Ghost admin access steps

Enable the Ghost membership feature

  1. Within the Ghost Admin, go to Labs and toggle “Enable Members” (more explicit instructions if needed)
  2. Fill in your Stripe API keys (can click the link beneath the Stripe input boxes for easy access)
  3. Enter the cost of your monthly and yearly subscriptions
  4. If you want to set up a free trial, read how to do so here
  5. Download a .zip of a Members enabled theme (default theme link // my forked theme // see my forked theme in action)
  6. Go to Ghost Admin>Design and upload your .zip of the theme under “Installed Themes”
  7. Activate your theme
  8. Once the theme is activated, unzip the theme .zip on your computer, and find the routes.yaml file inside of it. Upload this file to Ghost Admin>Labs>Routes.
  9. Review the rest of the Ghost Admin>Labs>Members settings, except for Email settings. We’ll come back to this one.
  10. If I’m missing a step or you get stuck, tweet me @elijahmurray

Manage your domain with Route53 in AWS

In order to have a custom domain with AWS, you need to setup a custom domain in AWS’s domain management tool, Route53. Depending on where you you bought your domain, these settings might be a little different.

Generally you can Google, “how to setup Route53 with MY_DOMAIN_REGISTRAR”. I recommend Namecheap personally, as I’ve found them the easiest to work with.

Setup Elastic IP Address

First, we need to setup an elastic IP. I could get into explaining what and why you need an elastic IP buuuuut, just go Google it if you’re curious.

  1. Within AWS, on the left hand panel under “Network & Security” click “Elastic IPs”
  2. Click, “Allocate Elastic IP Address”
  3. Leave everything as default, and click “Allocate”
  4. With your newly minted Elastic IP selected, in the top right click Actions>Associate Elastic IP address
    1. Resource type: Instance
    2. Instance: click into field, and select your Instance from the dropdown (this is the EC2 Instance that we created earlier)
    3. Skip the rest and click, “Associate”
  5. Confirm your Elastic IP address is working by going to the IP address listed in the, “Public IPv4 address” column. If your site loads, it’s working. If not, tweet at me @elijahmurray or cry
  6. Save this Elastic IP address for easy access, as it’s needed in the next step

Setup Custom Domain

  1. Open Route53 in AWS (Services in the top left, and then type Route53)
  2. Click “Create Hosted Zone”
    1. Type your custom domain in the Domain Name (type it naked, as in, not
    2. Click “Create”
  3. Click into your newly created Hosted Zone (it’ll show up as your URL in the left panel)
  4. You’ll see two records by default, a NS and a SOA.
  5. Use the NS (Name Server) records to configure your registrar with Custom DNS settings. If you get stuck on this, google it. Each Registrar is slightly different, but it should be well documented unless you have a shitty registrar. Here’s how to do it for Namecheap
  6. Lastly, let’s connect our IP address to our new domain. Click “Create Record Set”
    1. Name: leave blank
    2. Type: A
    3. Value: paste in your Elastic IP address
    4. Click “Create”
  7. And let’s make sure it works for the address as well…Click “Create Record Set”
    1. Name: www
    2. Type: A
    3. Value: paste in your Elastic IP address
    4. Click “Create”
  8. Confirm your handiwork by visiting your custom domain (i.e. AND If your site loads, the custom domain is working. Everyone says, “this can take up to 24 hours”. In my experience, it’s live within 5-10 minutes.
  9. Extra help: A Namecheap / AWS tutorial with pics

Setting up email and Mailgun

There are two places that you need to configure your Mailgun account. This is not intuitive in the Ghost documentation.

This is because the mailgun settings within the Ghost Admin portal are for transactional emails, specifically newsletter emails, and the other settings are for sign in/sign up emails. Luckily I struggled with this so you don’t have to.

Creating a Mailgun Account

  1. Create a mailgun account with your credit card
    1. Credit card verify your account (this is stupid but important they don’t charge anything as far as I can tell, but do it “to prevent spammers” 🙄)
    2. Email verify your account
  2. Note, if you aren’t setting up a custom domain you’ll need to add your test email address to mailgun (i.e. the email you’re entering within your website as a test). You do this by adding an Authorized Recipients within Mailgun. Read here.
  3. Click “Add New Domain” on the Domains page
  4. Set the Domain name to your domain, but add mg in front of your URL (i.e. “”), and click “Add Domain”. The mg subdomain is a best practice, but not necessary.
  5. Back within AWS’s Route53, create the records as outlined in Mailgun from the above step.
    • 2 TXT records, 2 MX records, and 1 CNAME record. Note: When setting the MX records in Route53, set the value to be “10” and “10”. This is how Route53 accepts the Priority field.
  6. Click “Verify DNS Settings”. Again, they say 24 hours, but this was live as soon as I finished creating the DNS records for me.
  7. If you have questions on mailgun, don’t tweet at me.

Update Ghost Admin configs for mail

  1. With Ghost Admin, go back to Settings>Lab>Members and expand the Email settings
  2. Mailgun domain: type in your custom domain (i.e. “”)
  3. Mailgun API key: click “Find your Mailgun API keys here”, and copy and paste your private API key
  4. Hit save

Update SMTP settings for mailgun

  1. Get and save for later your SMTP Settings from Mailgun to the side

    1. Within Mailgun, go to Sending>Domain Settings
    2. Make sure your custom domain is selected in the top left dropdown
    3. Copy the Login (starts with postmaster@……)
    4. Click “reset password” and copy the password when it’s shown to you
    5. Save the user and password for later
  2. Using the keypair that we downloaded during the Instance setup (way back when), SSH into the Instance from your Terminal. Make sure to not copy pasta “”, and update it to be your custom domain.

    1. ssh -i "mysite-keypair.pem"
  3. Open and edit /opt/bitnami/apps/ghost/htdocs/config.production.json. You’ll need to use nano or vim to edit the file on the server. Your on your own for this, but google “vim” and follow the instructions veeeery slowly.

  4. Replace the "mail" section in the config.production.json file with the below:

    "mail": {
        "transport": "SMTP",
        "options": {
            "service": "Mailgun",
            "auth": {
                "user": "",
                "pass": "1234567890"
  5. Make sure to set the "user" and "pass" fields to what the values you got from Step 1

  6. Save and close the file

  7. Restart ghost and apache by running the below commands, one after another:

    1. sudo /opt/bitnami/ restart ghost
      sudo /opt/bitnami/ restart apache
  8. Confirm everything worked. You should now be able to go to your website and subscribe. You should receive an email from your site to confirm your subscription.

  9. Additionally, once you’re subscribed, create a new post and publish it as a newsletter and confirm you should be able to create a new post, and publish it as a newsletter to confirm you receive the post in your inbox. Instructions on how to do this if you’re out of the loop

Sheeeeesh that was exhausting to write. Hopefully you found it helpful! If you want to support me, consider signing up for my personal growth newsletter,, where I send helpful tactics emails out once a week.

Or if you’re not interested in personal growth, consider subscribing or following me on Twitter.

Any questions? Tweet me.

Bonus: Disable bitnami banner

Bitnami has a stupid banner when you install it. To remove it:

  1. SSH in to your instance, and run:

  2. sudo /opt/bitnami/apps/ghost/bnconfig --disable_banner 1

Supporting source

Bonus: Setup SSL / HTTPS for free

If you want to go the extra mile and setup SSL, don’t try going through the integrations for Let’s Encrypt / SSL on Ghost’s marketplace. It didn’t work. Instead, do the following:

  1. SSH in to your instance, and run:

  2. sudo /opt/bitnami/bncert-tool
  3. Follow the prompts from the script

  4. Once the script is finished, update the url attribute in /opt/bitnami/apps/ghost/htdocs/config.production.json to be: "url": ""

  5. Update apache to prevent an infinite redirect. Open /opt/bitnami/apache2/confi/httpd.conf

    1. Search the file for ServerName and add the following line just above it:
    2. RequestHeader set X-Forwarded-Proto "https" (source)
  6. Restart ghost and apache by running:

       sudo /opt/bitnami/ restart ghost
       sudo /opt/bitnami/ restart apache
  7. Confirm it’s working. Now if you visit your site, you should be redirected to every time.
  8. It might take a bit for the SSL to update. You can try a different browser if it’s not working right away, as some times the DNS gets cached.

Supporting source and source