How I self-host this page

How I self-host this site. An in-depth guide.

How I self-host this page

Before I show you how I self-host this site, let me clarify. This isn't an optimal setup and has a long way ahead of itself to become one. As one of my first homelab projects, this is my attempt to be able to document the journey of learning this will bring me on.

Before we get started, I would recommend some basic knowledge of networking, Docker, and your own hardware if you plan to self-host. These aren't mandatory to follow, but I would recommend them anyway.

This site is hosted on a UGREEN NASync DXP4800 Plus upgraded to 32 GB of RAM. As you might imagine, it is completely overkill for just hosting a blog read by at most 100 people a day. Ghost uses so few resources, that it doesn't make even a dent in the task-manager's CPU and RAM graphs. I can't comment on how much the utilization will change with more visitors, but it most likely will not have too much of an impact. For starting with hosting a Raspberry Pi 4th or 5th gen should be more than enough or if you are just getting your feed wet, you can host it on your machine. Keep in mind that the machine you run Ghost on should be on 24/7, otherwise, there is no website during the downtime. 🫠

Once you have decided what hardware you run on, install Docker if you haven't already. We are going to use a docker compose file to get our instance of Ghost up and running.

Quick sidenote on what Ghost is. Ghost is a Platform to create blogs, newsletters, or magazines. It manages posts and memberships if needed. In our case, it's great because you can either pay them for the services hosted by them, or host it yourself.

As mentioned, we will use docker compose to get the Ghost container working. Create a docker-compose.yaml file in the folder in which you want to create your Service.

version: '3.1'

services:
  ghost:
    image: ghost:5-alpine
    restart: always
    ports:
      - 2368:2368
    environment:
      database__client: mysql
      database__connection__host: db
      database__connection__user: root
      database__connection__password: your password
      database__connection__database: ghost
      url: https://kraegenbrink.com/
    volumes:
      - ./ghost/content:/var/lib/ghost/content
    networks:
      - cloudflareTunnel

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: your password
    volumes:
      - ./mysql:/var/lib/mysql
    networks:
      - cloudflareTunnel

volumes:
  ghost:
  db:

networks:
  cloudflareTunnel:
    external: true

This compose will create a container with the ghost:5-alpine image. We save data in the same folder in which the compose file is located. To make Ghost work with Cloudflare later on we need to define a subnet which in our case is called “cloudflareTunnel”, but you can change this name to anything.

To get this setup working, we navigate to the folder in which our docker-compose.yaml is located and run the following command.

docker compose up -d

Ghost should now start up a database container and the blog container. By now you have your blog running, and it should be accessible locally. ✅

If this is the case we can start assigning a URL to it. To accomplish this we will be using Cloudflare tunnels as you could have probably guessed by the name of the subnet. If you haven't already, create a Cloudflare account and register an IP. Once you have your IP navigate to the Zero Trust tab in the sidebar, and from there to networks and tunnels.

You should now be able to create a tunnel by following the instructions. Cloudflare should now give you ways to run the tunnel in any environment. We for our use case want docker.

docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token yourToken
💡
Before we can run this command in the terminal, we need to add a variable to it.
--network yourSubnetName

The variable defines that this daemon should run on the same subnet as our Ghost instance. This way both containers can talk to each other.

Now it's time to give your blog a proper domain. For that we go back onto the Cloudflare dashboard and create a new public hostname.

Here you can define the subdomain you want, and will be able to select your bought domain under Domains. Path we can leave empty. The important part is the Type and URL. The Type is http and for domain take the IP of your Ghost container as well as it's docker port. Do not use the port of your host machine.

And voilà Bobs your uncle. The blog should now be available through your set domain. To start making your first blog post just navigate to the path /ghost, register, and you are done.

If there are any questions, you can get in contact with me through the contact page. I hope you will have as much fun with this as I am having and happy blogging. 😊