GitHub

A single-node bulletin board system reachable over MeshCore direct messages. Runs in a Docker container on Unraid (or anywhere Docker runs) and talks to a USB-attached MeshCore companion device.

Authentication is implicit: a user's identity is their MeshCore Curve25519 public key, verified end-to-end by the protocol's encrypted DM channel.

Features (v0.1)

  • Public message boards (BOARDS, READ, POST)
  • Asynchronous user-to-user mail (SEND, INBOX, READMAIL, DELETE)
  • News headlines from configurable RSS feeds (NEWS)
  • Weather lookup via Open-Meteo (free, no API key, no blocking) (WX)
  • Admin commands (BAN/UNBAN, BOARD ADD/DEL, BROADCAST)
  • Onboarding flow — first-time users pick a display name
  • Rate limiting, audit logging, persistent outbound queue
  • Web dashboard on the health port — live status, usage history, log tail
  • Health endpoint for container orchestration
  • Prometheus metrics (optional)

Quick start

git clone https://github.com/shermozle/meshcore-bbs.git
cd meshcore-bbs
cp config/config.example.yaml data/config.yaml
# Edit data/config.yaml — set bbs.admin_pubkeys and weather lat/lon

Unraid — copy docker-compose.unraid.yml to your appdata, edit the device path, then:

docker compose -f docker-compose.unraid.yml pull
docker compose -f docker-compose.unraid.yml up -d

Future updates: re-run the same two commands.

Other Docker hosts:

# Find your companion's USB-serial path
ls -l /dev/serial/by-id/
# Edit docker-compose.yml — set the device path
docker compose up -d
docker compose logs -f

DM your BBS from any MeshCore client. The first message produces an onboarding prompt; pick a name with NAME <yourname> and you're in.

Documentation

Project layout

src/bbs/                  Application code
  __main__.py             Entry point
  config.py               YAML config loader
  db.py                   SQLite + migrations
  models.py               Domain models
  dispatcher.py           Inbound message routing
  commands.py             Command parser + registry
  rate_limit.py           Sliding-window rate limiter
  outbound.py             Persistent send queue worker
  onboarding.py           First-contact name-setting flow
  scheduler.py            Background jobs
  health.py               HTTP /health + /metrics
  dashboard.py            Web dashboard API + UI
  format.py               Packet splitting
  services/               News, weather, boards, mail, admin
  transport/              MeshCore interface (real + mock)
tests/                    pytest suite (74 tests)
docs/                     Deployment, architecture, operations, user guide
deploy/                   systemd unit, Unraid template
scripts/                  Helper scripts (seed, backup, inspect)

Development

uv sync --extra dev
uv run pytest
# Run locally with no hardware:
uv run python -m bbs --mock --config config/config.example.yaml --db /tmp/bbs.db

The --mock flag swaps in an in-memory transport so you can poke at the dispatcher without a companion device.

To populate a dev DB with sample boards, users, news, and mail:

.venv/bin/python scripts/seed_dev_db.py /tmp/bbs.db

License

GPL-3.0-or-later — see LICENSE.

Read the original on github.com ↗