I spent money on a domain so I might as well use it.

Ghost 6.0 - ActivityPub Is a Go

I'm excited self-host Ghost 6.0 and hook my blog up to ActivityPub.
Ghost 6.0 - ActivityPub Is a Go

When I first switched to Ghost I wrote about how ActivityPub integration was a main reason I chose it. More recently had written about how excited I was to get away from the modern SEO trap and hopefully find something like the old blogosphere.

Well the time is finally here. I've been haunting the GitHub notifications for changes to the project, watching the preview releases trickle by. As of today Ghost 6.0 is launched! The changelog is beefy, so I'm not looking to enumerate everything in it. The new ActivityPub integration is what I am most excited to write about.


Changes to Self-Hosting Ghost

The first thing to note is that setting up ActivityPub on a self-hosted instance of Ghost can be done to two degrees:

  1. You can run Ghost, but use their ActivityPub infrastructure at ap.ghost.org. This is subject to usage limits.
  2. You can run ghost and the ActivityPub server all on your own infrastructure.

I have currently achieved #1 but I am not yet at #2. This is because the self-hosted ActivityPub is still in a preview state. Setting everything up involves quite a bit of work and assumes you are installing on a dedicated server. Right now you can't just pull Docker images and go. You have to checkout a git repo and Docker Compose from there. To use their own words:

Ghost 6.0 represents the beginning of a major improvement to how Ghost is deployed. Up until now, Ghost has been installed with Ghost-CLI as a single app that runs on a VPS with one MySQL database, but our new social web and analytics features have been built as independent services that run alongside Ghost.

So, we're moving toward Docker Compose as the officially supported way to install, run and update Ghost. This is now available as a developer preview, and will become the default from Ghost 7.0 onward.

So I'm excited to see the project moving towards proper containerization, but am holding off since support is still in an early state. What's more I'm currently using the Unraid Community App for Ghost which will not work with this design. That's OK! The growing pains are worth the change.

Also, the docs are a little scattered right now:

  • There is this Docker guide on the official site, but its not complete yet.
  • There is a guide on Notion that may have been a draft version of the docs.
  • People on the forums are also foaming at the mouths to figure out how to set ActivityPub up for themselves.

Regardless I was able to make #1 work.


Getting My Self-Hosted Instance to Work With Ghost's

Hopefully this goes without saying, remember to have a backup before you upgrade. [^ You should actually always have backup, but in this case especially.]

First I did a Docker update to pull in the 6.0 version of the container. Then I saw the new "Network" section in the admin panel. However is was non-functional. The logs for Ghost revealed a number of 404s on pages starting with .ghost. So I did some snooping around.

I noticed the new guide has language around Caddy, which I use, and not just nginx. We love this. I found the docs source in Github and did a blame to find the commit with all the Caddy additions. This was a useful starting point, but not the whole picture. The repo for the Docker Compose based installation contains the actual snippets to use in a Caddyfile. In particular there was an ActivityPub caddyfile snippet that had handle sections for redirecting the .ghost endpoints to an ActivityPub Server. The snippet uses a ACTIVITYPUB_TARGET variable that I realized defaults to ap.ghost.org when not overridden with a local server. So I updated my caddyfile to have an entry similar to:

https://blog.matthewbrunelle.com {

	handle /.ghost/activitypub/* {
			reverse_proxy https://ap.ghost.org
	}

	handle /.well-known/webfinger {
			reverse_proxy https://ap.ghost.org
	}

	handle /.well-known/nodeinfo {
			reverse_proxy https://ap.ghost.org
	}

	reverse_proxy ghost:2368 {
			header_up Host {host}
			header_up X-Real-IP {remote_ip}
			header_up X-Forwarded-For {remote_ip}
			header_up X-Forwarded-Proto {scheme}
	}
}

With that, a restart of Caddy and Ghost, and the Network integration was live! You can see my blog's profile now. One Side note about the Ghost network. The admin settings on my blog had this new notice:

Share growth data to rank higher?
Enabling this will use your revenue/member growth data to rank your site more highly on Ghost Explore. Total member count will be displayed publicly, other data will be kept private.

I've left this toggled off for now, until I better understand just what is shared.


Whats This Tinybird Thing?

OK, I'll talk about one other new feature, but only because I also spent a lot time poking around. In 6.0 the internal site analytics were overhauled. This leverages an analytics platform called Tinybird. Some thoughts from when I explored this today:

  • A built in analytics solution is appealing because I could avoid injecting a script.
  • You can't really self-host Tinybird. To use their phrasing you can only "self manage" the workspace. That keeps the data on your machine, but requires you to still go through their cloud platform.
  • The analytics do not seem to have every detail that I'd like. Mainly, details like referrer information.

Because of this I think for now I'm going to stick with Umami. Especially since the upcoming 3.0 release should improve the ergonomics.


So Whats Next?

My plan going forwards is to spin up a test instance using the new Docker Compose based setup. Then I'll test the self-hosted ActivityPub server. If that goes well I can import everything into the new instance and cut-over. Hopefully as that happens the documentation will be clarified too.

Anyways, I'm excited to finally see this all coming together and looking forward to see how we all build on this foundation!

Member discussion