Setting up Ghost

What better a first topic to write about than going through the process of setting up Ghost, the app that powers my blog.
Similar to how most of my Projects begin, I took a quick look over at this GitHub repo which contains a ton of useful information about countless self-hostable softwares for all sorts of situations. I constantly find myself back at this repo when looking for new ideas, so found it worth sharing.
I had personally tried out a few of the different Blogging Platform options on the list from awesome-selfhosted. Nothing really stood out to me, but I found Ghost to be easy enough to set up, and seems easy enough to manage so went with that. It does have quite a few extra features I don't need, but I'm not going to complain about them being there in the event I ever want to use them going down the line. An important part to me though is that it is Open Source.
Hosting Solution
I decided to host this blog on a small VPS rather than running it on my Lab infrastructure.
While I could host this internally, I wanted to get something for this set up now, and then can continue to iterate on it going forward. I may end up bringing the blog into my hosted infrastructure one day, but for now it will live in Digital Ocean. I already have a few other services running in DO, so it made sense to just add an additional instance there for this.
Deploying Ghost
While I normally like to containerize things if at all possible, DO actually has a ready to deploy app in their Marketplace for Ghost. I may install Ghost in docker down the road, but for now I'll run with this.
This made deploying Ghost extremely easy. While I could have done the manual steps in the documentation, why not use the automation that someone else already built for you? That being said, I fully support and encourage deploying apps like this manually to understand how the pieces all work together. I have deployed Ghost manually before, but opted to take the quicker way and same myself some time.
The install documentation for Ghost is pretty good, I'll also link to it below!
I could have just made this a subdomain of another domain I already have, but figured why not get the .blog TLD too. So I picked up nerdbox.blog and added 2 A records for the instance's public IP.
Now I was ready to ssh into the instance, and was met with the initial setup for Ghost. You will prompted about what we need to successfully install Ghost with; your blog URL and email address.
After pressing enter, the automated setup starts and eventually gets to the point of prompting for blog URL which we provide https://nerdbox.blog/ for. It later prompts for email address which I provided my gmail address.
Once this is provided Ghost handles setting up an acme.sh automation which uses LetsEncrypt to provision SSL Certificates for the website. I use LetsEncrypt quite a bit throughout my lab, so continuing to use them here was a no brainer, plus its built into the app already! If you look at the certificates securing this site you can see that in action.
I was then able to log in and set up the initial Blog at https://nerdbox.blog/
Additional Work
At this point the install of Ghost was completed and the base blog was reachable but my work on the instance running the app was not complete. Digital Ocean is good about securing their instances, and you need to take multiple steps to configure your OS in an unsafe manner. They however do not install fail2ban out of the box, which I like to have on anything I host, but especially on something that has publicly accessible ports like this instance does.
I normally run a pretty simple sshd jail with a configuration like the below. I also layer Crowdsec on top of this for additional security.
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
banaction_allports = iptables-allports
bantime = 86400
findtime = 10m
maxretry = 5
Wrap up
After this I was able to start testing out configurations within Ghost and start configuring the blog more for myself, and starting to personalize it, and then I got started on this post.