How to set up a free JAMstack-based Ghost blog with Heroku, Gatsby, GitHub and Netlify
Tags: jamstack, ghost, heroku, gatsby
Published: 2020-05-27 17:14:42

---
title: How to set up a free JAMstack-based Ghost blog with Heroku, Gatsby, GitHub and Netlify
published: true
date: 2020-05-27 16:51:27 UTC
tags: jamstack,ghost,heroku,gatsby
canonical_url: https://emtr0.dev/how-to-set-up-free-jamstack-ghost-blog-heroku-gatsby-github-netlify/
---

![How to setup a free JAMstack-based Ghost blog with Heroku, Gatsby, GitHub and Netlify](https://res-3.cloudinary.com/htgahrhjj/image/upload/q_auto/v1/ghost-blog-images/ghost-headless-feature-image.png)

> Posted on [emTr0.dev](https://emtr0.dev/how-to-set-up-free-jamstack-ghost-blog-heroku-gatsby-github-netlify/)

emTr0.dev is now pretty much how I want it in terms of design and setup (comment system coming soon) so [as promised](https://emtr0.dev/emtr0-dev-powered-by-ghost-heroku-gatsby-netlify-work-in-progress/), here's a quick guide on how I got everything working. The sources for this guide as well as additional resources for the platforms are linked at the end.

Before jumping into it, I wanted to mention the GitHub Student Developer Pack. If you're currently a student interested in anything related to developing websites and software, domains, security, productivity and more, you can sign up here:

[GitHub Student Developer Pack](https://education.github.com/pack)

The Dev Pack includes (typically) a year of free access to some of the premium services I use in this guide. The way I set things up keeps everything completely free for the average user but if you're looking to do more than what the free versions allow you to do, you'll at least have a year or so of free access as a student.

The final product of this guide will be a JAMstack-based website. What is [JAMstack](https://jamstack.org/)?

> You may have already seen or worked on a Jamstack site! They do not have to include _all_ attributes of JavaScript, APIs, and Markup. They might be built using sites built by hand, or with Jekyll, Hugo, Nuxt, Next, Gatsby, or another **static site generator**...  
>   
> The thing that they all have in common is that they don’t depend on a web server.

While the end-product of this guide will indeed be a JAMstack site, our use of a Heroku web server to run the actual Ghost installation kind of makes it a hybrid. They're still independent of each other so if Heroku goes down, your site won't. The benefit of using Heroku is you can access the Ghost CMS from anywhere vs just pushing to GitHub from a local installation, where you'd only be able to make changes from that same computer. Using the JAMstack version also minimizes the use of your Heroku resources and you'll also be able to get a free SSL certificate with Netlify, where you'd need to upgrade to get that with Heroku. Moving on...

What you'll need for this guide:

- Free [Heroku](https://signup.heroku.com/) account.
- Free [GitHub](https://github.com/join) account.
- Free [Netlify](https://app.netlify.com/signup) account.
- Custom domain (optional but recommended for that "professional" look, available free through some services in the Dev Pack).

Once you created the above accounts, [use this link](https://heroku.com/deploy?template=https://github.com/snathjr/ghost-on-heroku) to one-click deploy a Ghost v3.X installation to your Heroku account. Make "App name" something unique. For my site, I used "emtr0-dev" since my custom domain would eventually be emTr0.dev. Make sure you set the APP\_PUBLIC\_URL under the "Config Vars" section to this app name for now. You'll change this later as you integrate the rest of the JAMstack setup.

This one-click deploy option automatically sets up accounts for the following:

> [Cloudinary](https://cloudinary.com/) : To store images and video resources; You can replace Cloudinary with S3.   
>   
> [JawsDB MySQL](https://www.jawsdb.com/): To store actions, emails, integrations, members, permissions, posts, posts meta, roles, tags, settings, users etc. From Heroku app overview page, click on the JawsDB add-on you installed to access your JawsDB database dashboard. You can use the credentials and MySQL Workbench to connect to your JawsDB to access your data.  
>   
> [Mailgun](https://www.mailgun.com/): To send, receive and integrate emails. Your blog collaborators must be authorised receipents and agree to receive emails before they will receive emails from Mailgun.

We won't really be using these service but I did occasionally use Cloudinary to host some images that I used in the theme's design, so that's handy. If you decide to use Heroku to serve your Ghost site instead of the JAMstack site with GitHub and Netlify, you'll also have that option at this point and don't need to continue the guide. If you want to do that, just scroll down to the bottom and refer to the Heroku docs on how to setup a custom domain. Remember though, you won't get a free SSL certificate if you use Heroku this way.

Once you complete the Ghost setup on Heroku, go to https://YOURAPPNAME.herokuapp.com/ghost and finish setting up your admin account to access the CMS.

Once you're done setting up your Ghost installation on Heroku, [use this link](https://app.netlify.com/start/deploy?repository=https://github.com/TryGhost/gatsby-starter-ghost) to deploy a Gatsby Starter Theme for Ghost on Netlify (from the [Ghost GitHub repo](https://github.com/TryGhost/gatsby-starter-ghost)). The process will walk you through connecting your GitHub and Netlify accounts, and then setting up a repo for the files that will be served by Netlify. Feel free to make this repo private if you'd like. The auth connection allows the repo to be private without losing access to what needs to be served.

Next, you'll need to connect your Heroku Ghost installation with your GitHub/Netlify site. This is what makes Ghost "headless", allowing you to serve your content through the Netlify-served static website. To do this, go into Heroku Ghost > Integrations > + Add custom integration. You can name this integration anything but the most appropriate name would be "Gatsby". Copy the "Content API Key" and "API URL" and save these somewhere you can easily access for an upcoming step.

Go to your GitHub repo > .ghost.json file and edit it right inside GitHub. Replace the "apiUrl" and "contentApiKey" with what we just copied from the Gatsby integration. Save the changes.

Next you'll need to create a hook/webhook to make sure your changes in the Heroku Ghost CMS are being deployed by Netlify on your static site. First go into Netlify > Your site > Settings > Build & deploy > scroll down to "Build hooks" and click "Add build hook". Appropriately name it Ghost, leave "Branch to build" as master and then click save. Copy the generated URL.

Go back to your Heroku Ghost > Integrations > create a "Netlify" integration and then under "webhooks" click "+ Add webhook". Name it something like "Build", set the Event to "Site changed" and then paste in the URL you copied from Netlify. Click create to finish the setup.

The next step would be to setup your custom domain. I waited until I had my site at least 90% ready to go since emTr0.dev was previously active, and I didn't want anyone seeing it before it was ready. Once you're ready though, go into Netlify > Settings > Domain management and set up your custom domain there. You'll have to make changes to your domain's DNS settings if it's managed elsewhere and make sure you copy your MX records over to Netlify if you use that domain for email.

Lastly, you need to update your domain settings everywhere to make sure everything is referenced correctly internally. Go into Heroku > Your site > Settings > Reveal config vars and update "APP\_PUBLIC\_URL" to your domain which in my case was [https://emtr0.dev/](https://emtr0.dev/). Save that and then go to GitHub > Your site repo > src > utils > siteConfig.js and update the settings appropriately. You may need to update the theme files if your initial link exists somewhere that wasn't automatically updated with a Netlify build from your Ghost site. If you used your domain for another site, you can [set up redirects](https://docs.netlify.com/routing/redirects/) to direct visitors appropriately when they click on an old or broken link.

A follow-up change I made (that's optional for you) was adding external link indicators to external links in my site's navigation bar and footer. As you can see, my GitHub and Ko-fi links have icons that let you know you'll be opening another tab by clicking on them. Instructions on how to do this with a resource for icon images are included below. I plan to also do something similar for post/page links but haven't figured that one out yet.

That's it! I hope you found this guide useful. If I missed something or have bad info somewhere, please let me know. I should have my commenting system up and running later today but you can always reach out to me on [Twitter](https://twitter.com/emTr0), [Instagram](https://instagram.com/emTr0) or [Facebook](https://facebook.com/emTr0).

Thanks for stopping by!

<!--kg-card-begin: markdown-->
## Sources:
<!--kg-card-end: markdown-->

[Create a free JAMStack blog using Ghost, Heroku and Netlify](https://medium.com/@zingzai/create-a-free-jamstack-blog-using-ghost-heroku-and-netlify-7727d82ae56b)

[Use Ghost as a Headless CMS for static site - Gatsby + Netlify](https://hooshmand.net/how-to-headless-cms-static-page-gatsby-netlify-ghost/)

[Ghost Netlify Integration](https://ghost.org/integrations/netlify/)

[Adding External Link Indicator with CSS - Waaz Solutions](https://waaz.xyz/adding-external-link-indicator-with-css/)

[Open in new window Icons - Free Download, PNG and SVG](https://icons8.com)

<!--kg-card-begin: markdown-->
## Additional resources:
<!--kg-card-end: markdown-->

[Ghost Docs](https://ghost.org/docs/)

[Documentation | Heroku Dev Center](https://devcenter.heroku.com/categories/reference)

[Gatsby.js Documentation](https://www.gatsbyjs.org/docs/)

[Netlify Docs](https://docs.netlify.com)