Activitypub doesn't work! (LOADING INTERRUPTED)

This Self-hosting thing is NOT for the weak! :laughing: I have been trying to wrap my head around the documentation for actvitiypub and successfully installed ghost 6 from 5.0 version. Everything works well EXCEPT for activitypub and analytics with tinybird. I decided to ditch tinybird for now to fix this issue as I really want to use activitypub. After double and triple checking the .env file, my ssl-conf and conf files I set up. I don’t know what I missed. I do not use Caddy integration as I didn’t edit my admin portal. I use NGINX as my reverse proxy, and I set it up as instructed, and I keep ending up with a “loading interrupted” error for activity pub. I can see the dashboard for a second, before that error message pops up.

My configuration files for NGINX are located in the etc/nginx/sites-avaliable/, /sites-enabled/ and /var/www/ghost/system/nginx-root folder. I copy and pasted them into these three directories just in case. I don’t know if it needs to be in /var/www/ghost/system/nginx-root only or not but that’s where I put my files.

My .ENV file configuration

Use the below flags to enable the Analytics or ActivityPub containers as well
COMPOSE_PROFILES=analytics,activitypub

Ghost domain

Custom public domain Ghost will run on

DOMAIN=mywebsite.com

Ghost Admin domain

If you have Ghost Admin setup on a separate domain uncomment the line below and add the domain

You also need to uncomment the corresponding block in your Caddyfile

ADMIN_DOMAIN=

Ghost ports

Ports where Ghost will listen for HTTP traffic.

Change these if the default ports are in use, or if Ghost is behind a reverse proxy.

HTTP_PORT=80
HTTPS_PORT=443

Database settings
All database settings must not be changed once the database is initialised
DATABASE_ROOT_PASSWORD=(pw)

DATABASE_USER=optionalusername

DATABASE_PASSWORD= (pw)

ActivityPub

If you’d prefer to self-host ActivityPub yourself uncomment the line below

ACTIVITYPUB_TARGET=activitypub:443

Tinybird configuration

If you want to run Analytics, paste the output from docker compose run --rm tinybird-login get-tokens below

TINYBIRD_API_URL=https://api.us-east.aws.tinybird.co

TINYBIRD_TRACKER_TOKEN= (tracker token)

TINYBIRD_WORKSPACE_ID=(workspace ID)

Ghost configuration ( Configuration - Ghost Developer Docs )

SMTP Email ( Configuration - Ghost Developer Docs )
Transactional email is required for logins, account creation (staff invites), password resets and other features
This is not related to bulk mail / newsletter sending
mail__transport=SMTP
mail__options__host=smtp.mailgun.org
mail__options__port=2525
mail__options__secure=true
mail__options__auth__pass=(pw)
mail__from=“‘My username’ <postmaster@>mywebsite.com

Advanced customizations

Force Ghost version

You should only do this if you need to pin a specific version

The update commands won’t work

GHOST_VERSION=6-alpine

Port Ghost should listen on

You should only need to edit this if you want to host

multiple sites on the same server

GHOST_PORT=2368

Data locations

Location to store uploaded data

UPLOAD_LOCATION=./data/ghost

My .CONF file configuration

server {
listen 443 ssl http2;
server_name mywebsite.com;

# SSL configuration here...
location ~ /.ghost/activitypub/* {
    proxy_set_header        Host              $host;
    proxy_set_header        Authorization     $http_authorization;
    proxy_set_header        X-Real-IP         $remote_addr;
    proxy_set_header        X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_no_cache          1;
    proxy_cache_bypass      1;
    proxy_ssl_server_name on;
    set $upstream_app ghostactivitypub.rabbithole;
    set $upstream_port 80;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}

location ~ /.well-known/(webfinger|nodeinfo) {
    proxy_set_header        Host              $host;
    proxy_set_header        Authorization     $http_authorization;
    proxy_set_header        X-Real-IP         $remote_addr;
    proxy_set_header        X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_no_cache          1;
    proxy_cache_bypass      1;
    proxy_ssl_server_name on;
    set $upstream_app ghostactivitypub.rabbithole;
    set $upstream_port 80;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}



My SSL.conf configuration

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;

server_name mywebsite.com;
root /var/www/ghost/system/nginx-root; # Used for acme.sh SSL verification (https://acme.sh)

ssl_certificate /etc/letsencrypt/mywebsite.com/fullchain.cer;
ssl_certificate_key /etc/letsencrypt/mywebsite.com/mywebsite.com.key;
include /etc/nginx/snippets/ssl-params.conf;

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:2368;

}

location ~ /.well-known {
    allow all;
}

client_max_body_size 1g;

}
server {
if ($host = mywebsite.com) {
return 301 https://$host$request_uri;
} # managed by Certbot

listen 80;
listen [::]:80;
server_name mywebsite.com;
location / {
    proxy_pass http://127.0.0.1:2368;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ /.well-known {
    allow all;
}

}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mywebsite.com;
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
include /etc/nginx/snippets/ssl-params.conf;
location / {
proxy_pass http://127.0.0.1:2368;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~ /.well-known {
allow all;
}
}

Curious, did you perhaps take the .conf for nginx from one of my posts? Because youre using one of my servernames/domain in the .conf and that wont work for you since its internal to me only.

Are you trying to self host the multitenant activitypub project pulled down from their github as a server or bounce yours off of the Ghost platform one?

It looks like you have a LOT going on here that is tough to decipher, and probably needs a bit of a fresh start, you curiously have a location block in your ssl.conf…

edit: Yeah, it looks like you pulled that from this post Self hosted Ghost 6 on Raspberry Pi 5 via Cloudflare Tunnel: ActivityPub routes (.well-known, /.ghost/activitypub) failing with 403 - #4 by disgustipated
That block i pasted there was meant for that persons situation, the reference to “ghostactivitypub.rabbithole” needs to be replaced with the server name of the activitypub server if you are running it locally. the person on that thread was running the whole activitypub project on a server like myself, I believe most people self hosting ghost use the ghost provided activitypub server which i think its ap.ghost.org. someone else that is running that will need to help if youre not using the activitypub server from the ghost activitypub github as im not familiar with it. you do have some concerning things in your conf files though.

Yes, I was trying to figure out what was closest to my issue and tried solving it myself. I forgot to change it but thanks for confirming where I went wrong! I want to self-host it, as I do not want to have to figure this out later should I reach my max with activitypub if I use ghost’s servers.

I was planning to do a writeup on how i have the activitypub server running at some point, but my setup might be a little odd and difficult to follow due to the infrastructure i have set up

i cant do a full write up right now but if you want to run the activitypub server you have to do this

  1. git clone the code from the activitypub git
  2. modify the docker-compose to only run certain containers, the one in the project is not fully needed
  3. run docker compose up activitypub nginx -d --build && docker compose logs -f

Apologies, as I dont have much time at the moment but the containers im running from the activitypub compose file are below. i modified a lot of the variables and moved the volume mappings to different locations that what is listed in the projects compose. These are the ones that are needed when you run the compose up/build command above
services:
activitypub:
nginx:
redis:
pubsub:
fake-gcs:
migrate:

after this is running then you use the nginx conf to send the activitypub calls to the server you are running the above compose stack from

I took what you suggested here and troubleshooted from there, did a lot of legwork to implement this in my compose file in the right directory in ghost and I did a LOT of learning around docker’s mysql commands, building activitypub and the errors of my nginx file, configuring THAT correctly, and then getting ghost to handshake with activitypub to be active while also using the network feature in the back end. I got that figured out, and everything works smoothly now. Thank you for that response despite not having much time! I really appreciate it!