The Return of the Blog

Earlier this year, I decided to launch a blog. Just like everyone else in the world, their mom, and their dog, I wanted an outlet to share my thoughts.

However, when it came to actually launching my blog, I didn’t know where to start. With about  2847 platforms ready to power your blog, I was running into the paradox of choice. Should I choose Wordpress, a custom site, or just hand over my publishing to Medium?

The only thing that I became quickly sure of was that I wanted to host the blog on my own domain. I started off by looking for headless CMS tools, but quickly came to the determination that it wasn’t an optimal use of my time to design an entirely new front-end.

I asked a few friends for suggestions and the name Ghost kept coming up. Apparently, it was a well-optimized platform with a Medium-like UI that was made by an independent developer-all things that I loved hearing. So I decided to give it a try and upon doing some additional research, I settled on utilizing a $5 Digital Ocean droplet to serve it up.  [If you use this link, you'll get a free $50 credit]

Fast forward to 3 months later and my blog has seen over 100k pageviews with the Ghost and Digital Ocean combination totally holding up. It’s safe to say that I’m happy with my choice.

More recently, a couple readers have reached out looking for help in setting up the same publishing duo. The process is relatively quick, but not necessarily intuitive, so I thought I would compile the instructions into one easy blog post!

PS: This blog post is not sponsored by any third parties.

PPS: If you would prefer to write your own front-end, I would suggest Butter, a tool that I stumbled upon during my research which allows you to easily integrate into any backend. I actually implemented Butter into my Node application in a matter of minutes since their documentation is pretty solid, but ultimately wanted the Ghost front-end.

Ghost Premium?

Ghost is a “full-stack” publishing platform that allows you to set-up the front-end and back-end of your blog. Ghost also provides server support should you choose, which you can easily opt into with Ghost Premium. It’s simple and can be set up quickly, but costs $29/month for the most basic plan and as far as I know, most other features in Ghost Premium are available in the non-premium option, including integrations, code injection, and themes. The main differentiator is the lack of server set-up.

So, this article assumes that you don’t want to choose Premium and would prefer a cheaper server option like the $5 Digital Ocean Droplet One Click setup. Although not quite “one-click”, the following steps should also enable you to install Ghost with a private server, so that your new blog is up and running in a matter of minutes. Let’s jump in!

Ghost Setup with the Digital Ocean Droplet

Please note that this section will go through a step-by-step process of setting up self-hosted Ghost for domains (ex: domain.xyz) or subdomains (ex: blog.domain.xyz), but not subdirectories (domain.xyz/blog). There are additional steps that will not be covered in this article related to subdirectories.

Setting up the Digital Ocean Droplet (Server for Ghost)

  • The first step to setting up Ghost is hopping over to the Digital Ocean Marketplace. Search for “Ghost” and navigate to the Ghost droplet page. If you’re signed in, you can also find this in the platform by navigating to “Marketplace” in the left-hand navigation.
  • Click “Create Ghost Droplet”. This is the “Digital Ocean One Click” setup that will build and launch a server just for you!
  • Prior to creation, Digital Ocean will bring you to a page where you need to choose your droplet size. I would recommend that you start at the lowest tier which is: Standard $5/month. Note that this option doesn’t show up immediately, so you’ll need to navigate to the left to find it. Unless you already have a huge blog, I would not be concerned about traffic or the server holding up. My $5/month droplet held up with an article trending across the top of Hacker News for over 24h with hundreds of active readers and absolutely no glitches.
  • As for the other setup conditions, you can enable these at your discretion and are mostly optional. You will need to choose your datacenter region, which should be closest to where you expect most of your users/readers are. I did not select any additional add-ons or SSH key, as it’s not mandatory for set-up and my routing is done through Cloudflare which provides my security layer.
  • Once you’ve selected a name for your droplet (this can be anything), Digital Ocean will take a couple minutes to create the droplet. Once the droplet is created, you should see an IP address (for example: 134.209.253.151).
Once the droplet is set up, you can access your individual IP.
  • If you navigate to that IP in your browser, you’ll see the below view of the Ghost Installation page, which means the droplet is set up and hosted by Digital Ocean at that IP address. If you don’t see this page, the droplet has not been set up properly. If you do see this page, you’ve set up your droplet and can now connect it to a domain!
If you see this page at your IP, this means that you've installed the droplet properly.

Connecting to Custom Domain to Ghost

  • If you haven’t already purchased a custom domain for your Ghost blog, you’ll need to do that first. Remember, this process will work for either a completely new domain that you hope to use (ex: blog.xyz) or adding a subdomain to an existing domain hosted elsewhere (ex: blog.domain.xyz).
  • First, you’ll need to add the domain to Digital Ocean and set up your Digital Ocean DNS records. To do so, click the right-hand toggle to “Add a domain”.
Add your domain in Digital Ocean. 
  • Type your domain name in the input field and then click “Add Domain”. You should see DNS records populate similar to the below.
Once your domain is added in Digital Ocean, you should see the DNS records populate.
  • Once you’ve set up your DNS records on the Digital Ocean side, you’ll need to configure the A-record within your external domain settings. Depending on how you’ve set up your domain previously, but may be found within your domain registrar (ex: Namecheap, GoDaddy, etc.) or if you’ve already re-routed your DNS to a third party like Cloudflare, you would be updating the DNS records there. Within your non-Digital Ocean DNS records, you’ll need to direct your A-record to the IP given to your droplet with the “name” being the domain or subdomain where you hope to host your blog home.

    For example, if you wanted blog.domain.xyz to house the blog, you would set up the A-record for “blog” that to point towards the IP (ex: 134.209.253.151).

    Use the examples below as an example, but note that you should only set up one or the other.
An example of the DNS records in your third-party settings. 
  • Once you’ve set up your DNS records on both ends, they may take some time to propagate. Some third parties indicate that it can take up to 48 hours, but normally this happens within minutes.
  • Once the DNS records have propagated, you should once again see the same Ghost installation page at the domain or subdomain that you just configured. For example, this page would now show up not only at 134.209.253.15, but also makerstats.com. If you do not see this page, you may have to investigate whether the DNS settings have properly been set up and propagated.
You should see this page on your domain or subdomain if the DNS is set up and propagated.

Installing Ghost

  • The final section of this 3-step installation process is to install the Ghost software. To do so, hop back into Digital Ocean and open the console over on the right-hand side. This should open the console in a new tab that is requesting a login.
Access the Digital Ocean Console.
  • Enter your username (always “root”) and then the password sent to you by email from Digital Ocean, when you initiated the droplet.
Enter your login details into the Digital Ocean console.
  • The terminal will then prompt you to update your password immediately. This is mandatory.  It’ll first prompt you to enter your current UNIX password (same as password in your email) and then add a new password twice. If this is done correctly, you should see the installation initialize and after a few seconds, you should see the below screen.
The Ghost installation initializing.
  • Press enter to begin the installation to which you should see the program downloading.
You should see the prompts indicating that Ghost is installing.
  • The program will prompt you to enter your domain (in this case - make sure it’s your actual domain or subdomain and not the IP) and your email address. The email address can be any of your emails and is just used for the SSL process.
  • If everything is done correctly, this is what you will see!
Ghost has been installed!
  • To ensure that everything is set up properly, you can now go to your domain or subdomain and you should see a basic blog template from Ghost (example below). Note that if you’re routing through Cloudflare and you’re getting problems related to routing or too many redirects, you may be having problems related to your SSL. I was able to fix this in the Crypto tab, by setting SSL from Flexible to Full.
Template blog that should be found at your domain or subdomain.
  • Now, if you navigate to yourdomain.xyz/ghost or the subdomain.domain.xyz/ghost, you should see the setup page.
Ghost's sign-up page.
  • Once you go through the steps of the sign-up process, you should get to this page! This is your Ghost portal where you can customize, upload content, add integrations, and more.
The Ghost portal that can be found at anytime through your domain/ghost or subdomain/ghost.

Congrats! You’ve successfully set up Ghost. You will be able to access your editing platform at anytime through your link yourdomain.xyz/ghost or subdomain.domain.xyz/ghost. It’s time to get your blog up and running!

Getting Started with Ghost: Customization

In your portal, there are multiple tabs in the left-hand sidebar which allow you to further customize you blog. I’ll be going through some tips across each one of these below.

General

In this tab, you’ll enter a pretty standard set of information including your publication name, cover, logo (favicon), timezone, and more. Don’t forget to update your social accounts! I forgot to do this at first and had the Ghost social accounts as my default for over a week.

Another thing worth noting is that Ghost automatically adds a filter over cover images that are on the lighter end, in order for the text to show up clearly. You can edit this later in the code injection section.

General settings page.

Design

The navigation section is pretty straight-forward and allows you to set up your navigation bar, which is present on all pages of your blog. You’re able to set up links to any pages, whether internal or external to your blog, but most people utilize this to navigate to tags/category pages.

Navigation bar.
Navigation settings.

Ghost Themes

I’d say the one minor pitfall of Ghost currently is that customization is limited from a design standpoint. You can go and download the entire template, make changes, and then re-upload it. I decided to opt out of that approach and I have a feeling that many going through this tutorial will do the same.

Ghost themes available in the portal.

For those of you who also don’t want to edit an entire template, you do have the option to explore the Ghost theme marketplace. There are a couple dozen paid Ghost themes ranging from $19-$59, in addition to six free themes:

In the grand scheme of things, the cost of the paid themes is affordable and comparable to paid themes across other sites like Wordpress, but are much easier to install with Ghost.

Tags

You’ll need to select tags for your articles. These will be the categories which:

  1. Articles are grouped by
  2. Can be added to your navigation bar
Setting up tags in the portal.

You can add as many tags as you would like, along with a unique URL and description. For example, here is the Remote Work category for my blog. You’ll also be able to set up meta data, which is the information that will appear when the page is shared or shows up in search results.

I personally chose to select the same background image for all of my category pages. Instead of uploading them individually, I decided to set the image globally using CSS in the code injection section of the platform.

.site-header {
background-image: -webkit-image-set(
    url(https://images.unsplash.com/photo-1501769214405-5e5ee5125a02?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=998&q=80) 1x,
    url(https://images.unsplash.com/photo-1501769214405-5e5ee5125a02?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=998&q=80) 2x
)}  

Code Injection

Speaking of code injection, there are a few other ways to customize your design without directly editing the theme, but styling or adding scripts in your header/footer. Here are some things that I’ve chosen to do with code injection.

Google Analytics

Make sure that you add your Google Analytics tracking ID in your header. You can copy the script directly from Google Analytics.

<script async src="https://www.googletagmanager.com/gtag/js?id=UA-ID"></script>
<script>
	  window.dataLayer = window.dataLayer || [];
	  function gtag(){dataLayer.push(arguments);}
	  gtag('js', new Date());
	  gtag('config', 'UA-ID');
</script>

Additional Scripts

I also added a script to my Mailchimp modal and I’m sure that you can use your imagination for other scripts potentially worth adding.

Trust Bar

I decided to add a Trust Bar of places I had been featured. In order to do this, I added a div that was at the bottom of the header (under the styling and script tags). Below is some basic HTML to get you started along with the styling which can be found underneath.

<div id="trustbar">
As seen in:
<a href="https://www.producthunt.com/@stephsmith" target="_blank"><img src="https://stephsmith.io/featured/producthunt.png" class="trust-img"></a>
<a href="https://news.ycombinator.com/item?id=19163316" target="_blank"><img src="https://stephsmith.io/featured/hackernews.png" class="trust-img"></a>
<a href="https://hackernoon.com/a-year-of-sponge-3b4f48d00042" target="_blank"><img src="https://stephsmith.io/featured/hackernoon.png" class="trust-img"></a>
</div>

Additional Styling

Most elements can be styled with custom CSS. In order to determine what class or ID an element has, simply inspect the element and utilize that to modify with a style tag in the header.

<style>
/* Styling the trust bar */
    .trust-img{
        height: 20px;
        margin: 0 5px;
    }
    .trust-img:hover {
	height:22px;
	opacity: 0.8;
	}
    #trustbar{
        text-align: center;
        padding: 20px 0;
    }

/* Editing styles for description and nav bar */
    .site-description
    {
        font-weight: 500 !important;
    }    
    .site-nav {
        font-weight: 800 !important;
        text-shadow: 1px 1px rgba(0,0,0,0.3) !important;
    }    

/* Editing colour of bottom footer */
   .site-footer {
       background-color: rgb(245, 248, 251);
    }
    .site-footer-content, .site-footer-content a {
        color: grey;
    }
    }
    
/* Editing filter over cover image */
    .site-header:before{
        background: rgba(0, 122, 237, 0.23);
    }
</style>

The only thing that I’ve put in my Footer is the script to my Disqus comments. It’ll look something like this:

<!-- disqus -->
<script>
    // Only inject comments if you're on a post page.
    var article = $('.post-template main article');
    var disqusSite = 'YOUR_ACCOUNT';
    if (article.length) {
        article.after('<div id="disqus_thread"></div>');
        // this is the code you get from disqus
        (function() {
            var d = document, s = d.createElement('script');
            s.src = '//' + disqusSite + '.disqus.com/embed.js';
            s.setAttribute('data-timestamp', +new Date());
            (d.head || d.body).appendChild(s);
        })();
    }
</script>

Integrations

Ghost is known for being developer friendly and that includes easy access to integrations. In the Integrations tab, you can find a suite of Integrations. Feel free to explore them yourself, but I would specifically encourage you to set up the Integration with Zapier, which helps you “zap” any new subscribers from Ghost straight to your third-party list (ex: MailChimp). Simply click to configure the Zap and you will be brought straight to Zapier to set this up. Once set up, your set of steps should look something like this.

Ghost and Mailchimp integration utilizing Zapier.

Conclusion

And that’s it! Hopefully, if you went through each step of this process, you’ll have a fully set up Ghost blog app running on a kickass $5 Digital Ocean droplet. From here, it’s up to you to populate your beautiful new blog with some material. If any of the steps were unclear or did not work, feel free to send me a message - I’d love to help!

Happy writing!

PS: I love being able to share my thoughts with the world. If you like my work and want to support it in some way, feel free to buy me a chai or become a patron.


Related posts about Tech: