WordPress or nah?
Usually I like to set up websites using WordPress since I have a lot of experience with that and I can do it in my sleep. The problem with that is that I tried self-hosting WordPress at home before and it's a lot of work for a side project. So off to Google we go to search for alternatives!
Because containers are fun!
After digging around I also decided that maybe I want to try running the website in a Docker container since I've been teaching myself how to use Docker. After doing some more digging I found Ghost. I checked it out and it didn't look too difficult to set up. They were open-source and had a free self-hosted version (which this site runs on) so following the documentation from their Docker Hub repo, I went to work on customizing the compose file.
The following code comes from the official Ghost Docker Hub page.
version: '3.1' services: ghost: image: ghost:4-alpine restart: always ports: - 8080:2368 environment: # see https://ghost.org/docs/config/#configuration-options database__client: mysql database__connection__host: db database__connection__user: root database__connection__password: example database__connection__database: ghost # this url value is just an example, and is likely wrong for your environment! url: http://localhost:8080 # contrary to the default mentioned in the linked documentation, this image defaults to NODE_ENV=production (so development mode needs to be explicitly specified if desired) #NODE_ENV: development db: image: mysql:8.0 restart: always environment: MYSQL_ROOT_PASSWORD: example
I'll admit that I am a noob when it comes to yaml as I've only really used it when trying to set up ansible to test out on my Ubuntu systems here at home. It took me some tinkering, but I finally got a compose file that I was able to use to get this site up and running!
My modified code (with the password removed).
version: '3.1' services: ghost: image: ghost:latest restart: always ports: - 2368:2368 environment: database__client: mysql database__connection__host: db database__connection__user: root database__connection__password: super_secure_password database__connection__database: ghost url: https://blog.jermad14.com volumes: - /docker/ghost/content:/var/lib/ghost/content db: image: mysql:8.0 restart: always environment: MYSQL_ROOT_PASSWORD: super_secure_password volumes: - /docker/ghost/mysql:/var/lib/mysql
For my code I wanted to have the data persist on the system's local disk so I added in the volumes under each service. I also left the port as 2368 since I didn't have any other containers running on that port anyway. If this was a bad idea I'd love to know.
If you plan on utilizing this in production and/or using the built-in Stripe integration, make sure the URL is https and NOT http. It will not let you connect to Stripe if it's not a secure connection.
More than just cats!
I wanted my site to be available on the internet and not just in my internal network, so I set it up behind Nginx Proxy Manager (also running in a container). I already have an instance set up to host several other self-hosted web resources that I want to access outside of my home network so it was as simple as adding it as a proxy host. I also have wildcard SSL certs in NPM via Let's Encrypt so I don't have to worry about manually managing the SSL certs for my domains. Might make a post about how I set that up later.
Anyway, before all that I had to add the host to DNS and point it to my NPM instance. I use Cloudflare to manage my DNS and also point my internal network to Cloudflare as an upstream DNS server so I was able to hit the address almost instantly.
Setting it up in NPM was really easy because NPM is just like that. Just added the host (blog.jermad14.com), pointed it to the docker container and port number, and then selected my wildcard SSL to secure it. After all that I was able to access this website from my phone as well!
The rest of the time was just poking around the settings to see if there were things I wanted to change. I messed with some of the branding stuff, but for the most part everything else has been left at default so far. There were some pretty cool themes that are available for free, but for now I'm sticking with good ol' Casper (the friendly Ghost!).
Finally, if you're able to get to your website and show the default pre-installed content then you can run through the setup. Just add "/ghost" to the end of the URL and it will take you to the admin portal where you create your account and fill in some details.
So that was it for my journey installing Ghost in a container on my homelab server. Yes, server as in singular. Right now everything I'm running is just for my own personal learning where I can test stuff out that either intrigues me or is something I need a sandbox environment for so I can test things out. Maybe someday I'll expand it to more than just a server and NAS, but for now this works for what I need. I do have several containers running that I want to document so hopefully I don't get lazy and there will be more to come!