bzl

self-hosted ephemeral community engine
Log | Files | Refs | README | LICENSE

README.md (8870B)


      1 Bzl is a self-hostable, modular social platform designed for creators and communities who want full control of their space. Launch your own instance, extend it with plugins, and shape the experience to fit your world.
      2 
      3 🔗 Try the live dev instance: https://chat.bzl.one/
      4 
      5 🚀 Learn more & quick start: https://bzl.one/
      6 
      7 💬 Follow development in real time: https://chat.bzl.one/    REGISTRATION CODE IS "bzl" 
      8 
      9 If you're experimenting, building plugins, or just curious how Bzl works in the wild — jump into the official instance and say hi.
     10 
     11 
     12 
     13 # Bzl (MVP)
     14 
     15 Keyword-driven ephemeral posts ("pollination") that auto-expire after a TTL and broadcast live over WebSockets. Each post has a tiny chat room.
     16 
     17 Feed ordering:
     18 - Posts rise to the top based on recent chat activity (and manual boosts), not just creation time.
     19 - Other users can boost a post (+5m to +2h). Each chat message bumps the post (+2m, capped).
     20 - Posts and chat messages support emoji reactions (thumbs-up, heart, angry, sob, pleading, laugh-cry).
     21 - Hive feed supports filtering by keywords and author, plus sort modes (`Most recent activity`, `Most popular`, `About to expire`).
     22 - Users get private `Starred` and `Hidden` hive views (`⭐` reaction on hives stars them; hidden hives are user-local).
     23 - Hives are assigned to curated collections; compose includes a required collection selector and feed supports collection tabs.
     24 - Owner/moderator can define custom role tags and gate collections by base/custom role.
     25 - Clicking a member in `People` opens their profile view (bio, pronouns, theme song, and social links), with an in-panel editor for the profile owner.
     26 
     27 Media uploads:
     28 - GIF/image/audio attachments are uploaded to `data/uploads/` and referenced by short `/uploads/...` URLs.
     29 - This avoids massive WebSocket payloads from base64 data URLs and is more reliable for larger files.
     30 
     31 ## Docs
     32 
     33 - Full feature rundown (video script aid): `docs/FUNCTIONALITY_REFERENCE.md`
     34 - Plugins (MVP): `docs/PLUGINS.md`
     35 - UI rack layout (draft): `docs/UI_RACK_LAYOUT.md`
     36 - Directory plugins (draft): `docs/DIRECTORY_SPEC.md`
     37 - Moderation spec: `docs/MODERATION_MVP_SPEC.md`
     38 - Self-hosted installer plan: `docs/SELF_HOSTED_INSTALLER_PLAN.md`
     39 - Multi-instance docker stack: `docs/MULTI_INSTANCE_DOCKER.md`
     40 - Instance fleet automation (discovery + bulk update): `docs/INSTANCE_FLEET_AUTOMATION.md`
     41 - Issue tracker guide: `docs/ISSUE_TRACKER.md`
     42 - Updating a live server (git + docker): `docs/SERVER_UPDATE.md`
     43 
     44 ## Run locally
     45 
     46 ### Docker
     47 
     48 To run a local instance of the app, the following command can be used:
     49 ```bash
     50 docker compose -f compose.yaml up --build --remove-orphans
     51 ```
     52 
     53 Optionally the `-d` flag can be specified to let the app run as a background process.
     54 
     55 ### Manual
     56 
     57 1. Install Node.js (recommended: Node 18+)
     58 2. From this folder:
     59    - Optional first-time wizard: `npm run init` (Windows PowerShell: `npm.cmd run init`)
     60    - `npm install` (or `npm.cmd install` in Windows PowerShell if `npm` is blocked by execution policy)
     61    - `npm start` (or `npm.cmd start` in Windows PowerShell)
     62    - Recommended: GUI launcher: `LAUNCHER.cmd` / `LAUNCHER.ps1` (or `npm run launcher:ui`) — includes Cloudflare setup + core auto-update
     63    - Or a launcher (opens the URL when ready): `npm run launch`
     64    - Or launcher + Cloudflare quick tunnel: `npm run launch:tunnel`
     65 3. Open:
     66    - `http://localhost:3000`
     67    - or from another device on the same Wi-Fi/LAN: `http://<your-laptop-ip>:3000`
     68 
     69 If another device can't connect, allow inbound connections for Node on your firewall.
     70 
     71 Health check endpoint:
     72 - `GET /api/health` returns basic runtime status for setup/service checks.
     73 - Includes active rate-limit bucket count for diagnostics.
     74 
     75 ## Accounts (username/password)
     76 
     77 Posting and chat require signing in.
     78 
     79 Create users on the host machine (your laptop):
     80 - `node scripts/create-user.js <username>`
     81 - or `npm.cmd run create-user -- <username>`
     82 
     83 The users file is stored at `data/users.json` on your host (ignored by git).
     84 
     85 First-time setup option: if no users exist yet, you can create the first user from `http://localhost:3000` (loopback only).
     86 
     87 To let other people create their own accounts (useful over a tunnel), set a registration code on the host:
     88 - PowerShell (current session): `$env:REGISTRATION_CODE="some-long-random-string"`
     89 - Then restart the server.
     90 
     91 ## Backups and restore
     92 
     93 Runtime data can be snapshotted locally (users, posts, reports, mod log, sessions, uploads).
     94 
     95 - Create backup: `npm run backup-data`
     96 - List backups: `node scripts/restore-data.js --list`
     97 - Restore latest backup: `npm run restore-data -- --yes`
     98 - Restore a specific backup: `npm run restore-data -- --name <backup-folder-name> --yes`
     99 
    100 Notes:
    101 - Restore overwrites current runtime files in `data/`.
    102 - Restore automatically creates a `pre-restore-*` safety snapshot first.
    103 
    104 ## Service reliability (Windows)
    105 
    106 Run with supervision (auto-restart + health watchdog):
    107 - `npm run start:supervised`
    108 
    109 Install a startup task for your Windows user:
    110 - `powershell -ExecutionPolicy Bypass -File .\\scripts\\install-windows-startup.ps1`
    111 
    112 Remove startup task:
    113 - `powershell -ExecutionPolicy Bypass -File .\\scripts\\uninstall-windows-startup.ps1`
    114 
    115 Runner env vars (optional):
    116 - `HEALTHCHECK_URL` (default `http://127.0.0.1:<PORT>/api/health`)
    117 - `HEALTHCHECK_MS` (default `15000`)
    118 - `HEALTHCHECK_TIMEOUT_MS` (default `4000`)
    119 - `HEALTHCHECK_FAILS` (default `3`)
    120 - `RESTART_MIN_MS` (default `2000`)
    121 - `RESTART_MAX_MS` (default `30000`)
    122 
    123 ## Share beyond LAN (tunnel)
    124 
    125 If you want friends to connect from anywhere without port forwarding, run a tunnel on your host PC.
    126 
    127 Cloudflare quick tunnel (no router changes):
    128 1. Install: `winget install Cloudflare.cloudflared`
    129 2. Start Bzl: `npm.cmd start`
    130 3. In a second terminal run: `cloudflared tunnel --url http://localhost:3000`
    131 4. Share the `https://...trycloudflare.com` URL it prints.
    132 
    133 If you update the app and someone still sees an older UI, do a hard refresh (or open an incognito window). The server sets `Cache-Control: no-store`, but some browsers/proxies can still hold onto old assets briefly.
    134 
    135 Cloudflare named tunnel (stable URL):
    136 1. Put a domain on Cloudflare (DNS managed by Cloudflare).
    137 2. Authenticate `cloudflared` (one-time; opens a browser): `cloudflared tunnel login`
    138 3. Create the tunnel: `cloudflared tunnel create bzl`
    139 4. Route a hostname to it (example): `cloudflared tunnel route dns bzl bzl.yourdomain.com`
    140 5. Create a config file at `%HOMEPATH%\\.cloudflared\\config.yml`:
    141    - `tunnel: <TUNNEL-UUID>`
    142    - `credentials-file: C:\\Users\\<you>\\.cloudflared\\<TUNNEL-UUID>.json`
    143    - `ingress:` mapping your hostname to Bzl:
    144      - `- hostname: bzl.yourdomain.com`
    145        `service: http://localhost:3000`
    146      - `- service: http_status:404`
    147 6. Run it:
    148    - Foreground: `cloudflared tunnel run bzl` (requires the `config.yml` ingress rules)
    149    - One-off (no config): `cloudflared tunnel run bzl --url http://localhost:3000`
    150    - As a service: `cloudflared service install` (then it starts on boot)
    151 
    152 ## Environment variables
    153 
    154 - `PORT` (default `3000`)
    155 - `HOST` (default `0.0.0.0`)
    156 - `DEFAULT_TTL_MS` (default `3600000`)
    157 - `MIN_TTL_MS` (default `60000`)
    158 - `MAX_TTL_MS` (default `172800000`)
    159 - `USERS_FILE` (default `data/users.json`)
    160 - `POSTS_FILE` (default `data/posts.json`)
    161 - `COLLECTIONS_FILE` (default `data/collections.json`)
    162 - `ROLES_FILE` (default `data/roles.json`)
    163 - `UPLOADS_DIR` (default `data/uploads`)
    164 - `IMAGE_UPLOAD_MAX_BYTES` (default `104857600` = 100 MB)
    165 - `AUDIO_UPLOAD_MAX_BYTES` (default `157286400` = 150 MB)
    166 - `PROFILE_BIO_MAX_HTML_LEN` (default `120000`)
    167 - `PROFILE_PRONOUNS_MAX_LEN` (default `40`)
    168 - `PROFILE_LINK_LABEL_MAX_LEN` (default `40`)
    169 - `PROFILE_LINK_URL_MAX_LEN` (default `280`)
    170 - `PROFILE_LINKS_MAX` (default `8`)
    171 
    172 Startup validation:
    173 - Server validates critical env values at boot and exits with clear errors if invalid.
    174 
    175 Rate limits:
    176 - Auth: login/register/resume session are rate-limited.
    177 - Uploads: image/audio uploads are rate-limited per sender.
    178 - Moderation: report creation and moderation actions are rate-limited.
    179 - Server emits `rateLimited` messages over WebSocket and `429` with `retryMs` for upload API.
    180 
    181 Rate limit env vars:
    182 - `RL_LOGIN_WINDOW_MS` (default `60000`)
    183 - `RL_LOGIN_MAX` (default `12`)
    184 - `RL_REGISTER_WINDOW_MS` (default `600000`)
    185 - `RL_REGISTER_MAX` (default `6`)
    186 - `RL_RESUME_WINDOW_MS` (default `60000`)
    187 - `RL_RESUME_MAX` (default `30`)
    188 - `RL_UPLOAD_WINDOW_MS` (default `300000`)
    189 - `RL_UPLOAD_IMAGE_MAX` (default `20`)
    190 - `RL_UPLOAD_AUDIO_MAX` (default `10`)
    191 - `RL_REPORT_WINDOW_MS` (default `600000`)
    192 - `RL_REPORT_MAX` (default `12`)
    193 - `RL_MOD_WINDOW_MS` (default `60000`)
    194 - `RL_MOD_MAX` (default `40`)
    195 
    196 ## Open source
    197 
    198 Bzl is released under the MIT License. See `LICENSE`.
    199 
    200 Community docs:
    201 - Contributing: `CONTRIBUTING.md`
    202 - Security policy: `SECURITY.md`
    203 - Issue tracker guide: `docs/ISSUE_TRACKER.md`