Hi everyone,
I’m looking for help troubleshooting ActivityPub on a self hosted Ghost site.
Site + environment
-
Domain:
beitmenotyou.online -
Hardware: Raspberry Pi 5 (64 bit, arm64)
-
OS: Raspberry Pi OS Lite (64 bit)
-
Deploy: Docker Compose
-
Edge: Cloudflare Tunnel (cloudflared running in a container)
-
Ghost: previously Ghost 5, now updated to Ghost 6.14.0
-
We have had issues updating to Ghost 6.15.0 (happy to share logs if needed)
What works
-
The main site loads fine through Cloudflare Tunnel (homepage and normal pages render)
-
Containers are healthy and the tunnel connects
The problem
ActivityPub (Network feature) is not functioning properly. Discovery endpoints and ActivityPub endpoints are failing, and we are seeing errors like SITE_MISSING and inconsistent HTTP responses (502, 503, 530, 403) while trying different proxy approaches.
Current architecture (Docker Compose)
We’re running:
-
ghost(ghost:6-alpine) -
ghost-db(mysql:8.0) -
cloudflared-ghost(cloudflare/cloudflared:latest) -
ghost-proxy(nginx:alpine) to handle ActivityPub routing
docker compose ps shows:
NAME IMAGE STATUS
cloudflared-ghost cloudflare/cloudflared:latest Up
ghost ghost:6-alpine Up (ports: 127.0.0.1:2368->2368)
ghost-db mysql:8.0 Up (healthy)
ghost-proxy nginx:alpine Up
What we tried (chronological)
1) Tried self hosting the ActivityPub containers
We initially tried adding the official ActivityPub containers alongside Ghost:
-
ghcr.io/tryghost/activitypub -
ghcr.io/tryghost/activitypub-migrations
On the Pi (arm64), this failed due to image architecture mismatch. The migration container would not run and threw an exec format error.
Example of what we saw:
WARNING: The requested image platform (linux/amd64) does not match the detected host platform (linux/arm64/v8)
exec /usr/local/bin/up: exec format error
So we removed those services and moved on.
2) Tried proxying ActivityPub to hosted ap.ghost.org using nginx
We then switched to the “proxy ActivityPub to ap.ghost.org” approach.
We added this in the Ghost container environment:
ACTIVITYPUB_TARGET: https://ap.ghost.org
url: https://beitmenotyou.online
We created an nginx container (ghost-proxy) with a config intended to:
-
proxy
/.ghost/activitypub/tohttps://ap.ghost.org -
proxy
/.well-known/webfingerand/.well-known/nodeinfotohttps://ap.ghost.org -
proxy everything else to the local Ghost container (
http://ghost:2368)
Current nginx config looks like this:
server {
listen 80;
location ^~ /.ghost/activitypub/ {
proxy_pass https://ap.ghost.org;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ssl_server_name on;
proxy_ssl_name ap.ghost.org;
}
location = /.well-known/webfinger {
proxy_pass https://ap.ghost.org;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
proxy_ssl_server_name on;
proxy_ssl_name ap.ghost.org;
}
location = /.well-known/nodeinfo {
proxy_pass https://ap.ghost.org;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
proxy_ssl_server_name on;
proxy_ssl_name ap.ghost.org;
}
location / {
proxy_pass http://ghost:2368;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Cloudflared config validates:
cloudflared tunnel ingress validate
OK
Cloudflared connects successfully and shows the tunnel is live. We also see:
Updated to new configuration ... ingress ... hostname:"beitmenotyou.online"
Current symptoms and test results
Public tests (from the server)
Main site works:
curl -sS https://beitmenotyou.online/ | head
But ActivityPub / discovery endpoints fail.
Examples:
curl -sSIL "https://beitmenotyou.online/.well-known/webfinger/?resource=acct:admin@beitmenotyou.online" | sed -n '1,25p'
curl -sSIL "https://beitmenotyou.online/.well-known/nodeinfo/" | sed -n '1,25p'
curl -sSIL "https://beitmenotyou.online/.ghost/activitypub/v1/site/" | sed -n '1,25p'
We see a mix of:
-
HTTP/2 502(earlier when routing changes were wrong) -
HTTP/2 530(during some proxy attempts) -
HTTP/2 503(during some proxy attempts) -
and now consistently 403 with:
{"error":"Forbidden","code":"SITE_MISSING"}
We also sometimes see redirects like:
-
/.well-known/nodeinfo→/.well-known/nodeinfo/ -
/.well-known/webfinger→/.well-known/webfinger/
Internal tests (inside ghost-proxy)
From inside the nginx container we can hit the route and see nginx responding, but it still ends with a 403 coming back:
docker exec -it ghost-proxy sh -lc \
'curl -sSIL -H "Host: beitmenotyou.online" http://127.0.0.1/.well-known/nodeinfo/ | sed -n "1,25p"'
Result pattern:
-
302 Foundto the non trailing slash version -
then
403JSON
Extra notes
- cloudflared logs always include:
Cannot determine default origin certificate path. No file cert.pem ...
Tunnel still connects and the site loads, so not sure if this matters for ActivityPub.
- nginx logs show external ActivityPub style POST attempts hitting endpoints like
/inboxand/wp-json/.../inboxreturning 404, which suggests federation traffic is reaching the site but not being handled.
What I’m hoping the community can clarify
-
Is self hosting ActivityPub officially supported on arm64 yet? The official ActivityPub images we tried appear to be amd64 only, so they fail on Raspberry Pi.
-
For the
ap.ghost.orgreverse proxy approach, what does{"code":"SITE_MISSING"}actually mean in practice?
-
Is there a required registration or handshake step for self hosted sites?
-
Is this expected until some specific setting inside Ghost is enabled?
- Are there any known Ghost 6.14.0 issues (or 6.15.0 update issues) on arm64 that impact ActivityPub?
If anyone can point me at the correct “known good” setup for Cloudflare Tunnel + self hosted Ghost + ActivityPub, I’d really appreciate it. Happy to share full redacted configs and logs.
Thanks!
Optional context links (not required, but these match the errors we’re seeing):
Ghost forum thread about 403 SITE_MISSING on self host. (Ghost Forum)
https://forum.ghost.org/t/activitypub-error-forbidden-code-site-missing/57993
Ghost forum thread about self hosted ActivityPub 403 errors and proxy edge cases (JWKS endpoint mentioned). (Ghost Forum)
https://forum.ghost.org/t/fixing-ghost-activitypub-404-error-on-self-hosted-installation/60743
If you want, paste your current /opt/ghost/cloudflared/config.yml too (redact the token) and I’ll tweak the “Current architecture” section so it exactly matches what Cloudflare is routing to right now.