Files
thepraandClaude Opus 5.5 6b08da458a Pasture: NodeBB joins
NodeBB 4.16.1 runs in the pasture on the pasture's Mongo, set up by its
automated setup, with an API token written where NodeBB keeps them.
scenarios/nodebb.sh passes its 23 checks with no change to PrivaPub: a
category followed and its topic as a titled thread, replies both ways, a
follow of alice and her post there, votes both ways, an edit and a
deletion, a chat both ways, the unfollow and statistics.

NodeBB never federates a topic's lock, and its API follows an account
elsewhere only when named by its handle; both are in docs/INTEROP.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
2026-10-05 16:58:08 +02:00

39 lines
2.5 KiB
Bash

# NodeBB 4.16.1: forum software whose categories are ActivityPub groups and whose topics are threads; federation is on
# by default since 4.0. The official image on the pasture's Mongo (database nodebb), set up once by its automated setup
# (SETUP with NODEBB_* variables: admin nbuser), then started on that config, trusting the pasture's CA through
# NODE_EXTRA_CA_CERTS. Its image runs `npm install` at every start. Its API (/api/v3) takes a bearer token, which
# nodebb_settle writes into its database as NodeBB's own token list does (token:<t>, tokens:createtime, tokens:uid).
NODEBB_IMAGE=${NODEBB_IMAGE:-ghcr.io/nodebb/nodebb:4.16.1}
NODEBB_PASSWORD=NodeBB-Pasture-Pass-1
nodebb_up() {
podman volume exists pasture-nodebb-config || podman volume create --label pasture=1 pasture-nodebb-config >/dev/null
podman volume exists pasture-nodebb-uploads || podman volume create --label pasture=1 pasture-nodebb-uploads >/dev/null
local common=(--network $net --label pasture=1 -v pasture-nodebb-config:/opt/config:U -v pasture-nodebb-uploads:/usr/src/app/public/uploads:U
-v "$ca/bundle.pem:/ca/bundle.pem:z,ro" -e NODE_EXTRA_CA_CERTS=/ca/bundle.pem)
if ! podman run --rm "${common[@]}" --entrypoint test "$NODEBB_IMAGE" -s /opt/config/config.json; then
podman run --rm "${common[@]}" -e SETUP=true -e NODEBB_URL=https://nodebb.test -e NODEBB_PORT=4567 \
-e NODEBB_ADMIN_USERNAME=nbuser -e NODEBB_ADMIN_PASSWORD="$NODEBB_PASSWORD" -e NODEBB_ADMIN_EMAIL=nbuser@nodebb.test \
-e NODEBB_DB=mongo -e NODEBB_DB_HOST=mongo -e NODEBB_DB_PORT=27017 -e NODEBB_DB_NAME=nodebb "$NODEBB_IMAGE" \
> "$here/.state/nodebb-setup.log" 2>&1
fi
podman run -d --replace --name pasture-nodebb "${common[@]}" "$NODEBB_IMAGE" >/dev/null
for _ in $(seq 1 150); do
site nodebb.test -s -o /dev/null -w '%{http_code}' https://nodebb.test:6443/api/config 2>/dev/null | grep -q 200 && break
sleep 2
done
nodebb_settle
echo "nodebb: https://nodebb.test:6443"
}
# nbuser's API token, written where NodeBB keeps them
nodebb_settle() {
local token="pasture-nbuser-token"
podman exec pasture-mongo mongosh --quiet nodebb --eval "
const now = Date.now();
db.objects.updateOne({_key: 'token:$token'}, {\$set: {uid: 1, description: 'pasture', timestamp: now}}, {upsert: true});
db.objects.updateOne({_key: 'tokens:createtime', value: '$token'}, {\$set: {score: now}}, {upsert: true});
db.objects.updateOne({_key: 'tokens:uid', value: '$token'}, {\$set: {score: 1}}, {upsert: true});" >/dev/null
echo "$token" > "$here/.state/nodebb.token"
}