bzl

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

README.md (8972B)


      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 - DigitalOcean + domain deployment and monthly cost guide: `docs/DIGITALOCEAN_DEPLOYMENT_AND_COST.md`
     42 - Issue tracker guide: `docs/ISSUE_TRACKER.md`
     43 - Updating a live server (git + docker): `docs/SERVER_UPDATE.md`
     44 
     45 ## Run locally
     46 
     47 ### Docker
     48 
     49 To run a local instance of the app, the following command can be used:
     50 ```bash
     51 docker compose -f compose.yaml up --build --remove-orphans
     52 ```
     53 
     54 Optionally the `-d` flag can be specified to let the app run as a background process.
     55 
     56 ### Manual
     57 
     58 1. Install Node.js (recommended: Node 18+)
     59 2. From this folder:
     60    - Optional first-time wizard: `npm run init` (Windows PowerShell: `npm.cmd run init`)
     61    - `npm install` (or `npm.cmd install` in Windows PowerShell if `npm` is blocked by execution policy)
     62    - `npm start` (or `npm.cmd start` in Windows PowerShell)
     63    - Recommended: GUI launcher: `LAUNCHER.cmd` / `LAUNCHER.ps1` (or `npm run launcher:ui`) — includes Cloudflare setup + core auto-update
     64    - Or a launcher (opens the URL when ready): `npm run launch`
     65    - Or launcher + Cloudflare quick tunnel: `npm run launch:tunnel`
     66 3. Open:
     67    - `http://localhost:3000`
     68    - or from another device on the same Wi-Fi/LAN: `http://<your-laptop-ip>:3000`
     69 
     70 If another device can't connect, allow inbound connections for Node on your firewall.
     71 
     72 Health check endpoint:
     73 - `GET /api/health` returns basic runtime status for setup/service checks.
     74 - Includes active rate-limit bucket count for diagnostics.
     75 
     76 ## Accounts (username/password)
     77 
     78 Posting and chat require signing in.
     79 
     80 Create users on the host machine (your laptop):
     81 - `node scripts/create-user.js <username>`
     82 - or `npm.cmd run create-user -- <username>`
     83 
     84 The users file is stored at `data/users.json` on your host (ignored by git).
     85 
     86 First-time setup option: if no users exist yet, you can create the first user from `http://localhost:3000` (loopback only).
     87 
     88 To let other people create their own accounts (useful over a tunnel), set a registration code on the host:
     89 - PowerShell (current session): `$env:REGISTRATION_CODE="some-long-random-string"`
     90 - Then restart the server.
     91 
     92 ## Backups and restore
     93 
     94 Runtime data can be snapshotted locally (users, posts, reports, mod log, sessions, uploads).
     95 
     96 - Create backup: `npm run backup-data`
     97 - List backups: `node scripts/restore-data.js --list`
     98 - Restore latest backup: `npm run restore-data -- --yes`
     99 - Restore a specific backup: `npm run restore-data -- --name <backup-folder-name> --yes`
    100 
    101 Notes:
    102 - Restore overwrites current runtime files in `data/`.
    103 - Restore automatically creates a `pre-restore-*` safety snapshot first.
    104 
    105 ## Service reliability (Windows)
    106 
    107 Run with supervision (auto-restart + health watchdog):
    108 - `npm run start:supervised`
    109 
    110 Install a startup task for your Windows user:
    111 - `powershell -ExecutionPolicy Bypass -File .\\scripts\\install-windows-startup.ps1`
    112 
    113 Remove startup task:
    114 - `powershell -ExecutionPolicy Bypass -File .\\scripts\\uninstall-windows-startup.ps1`
    115 
    116 Runner env vars (optional):
    117 - `HEALTHCHECK_URL` (default `http://127.0.0.1:<PORT>/api/health`)
    118 - `HEALTHCHECK_MS` (default `15000`)
    119 - `HEALTHCHECK_TIMEOUT_MS` (default `4000`)
    120 - `HEALTHCHECK_FAILS` (default `3`)
    121 - `RESTART_MIN_MS` (default `2000`)
    122 - `RESTART_MAX_MS` (default `30000`)
    123 
    124 ## Share beyond LAN (tunnel)
    125 
    126 If you want friends to connect from anywhere without port forwarding, run a tunnel on your host PC.
    127 
    128 Cloudflare quick tunnel (no router changes):
    129 1. Install: `winget install Cloudflare.cloudflared`
    130 2. Start Bzl: `npm.cmd start`
    131 3. In a second terminal run: `cloudflared tunnel --url http://localhost:3000`
    132 4. Share the `https://...trycloudflare.com` URL it prints.
    133 
    134 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.
    135 
    136 Cloudflare named tunnel (stable URL):
    137 1. Put a domain on Cloudflare (DNS managed by Cloudflare).
    138 2. Authenticate `cloudflared` (one-time; opens a browser): `cloudflared tunnel login`
    139 3. Create the tunnel: `cloudflared tunnel create bzl`
    140 4. Route a hostname to it (example): `cloudflared tunnel route dns bzl bzl.yourdomain.com`
    141 5. Create a config file at `%HOMEPATH%\\.cloudflared\\config.yml`:
    142    - `tunnel: <TUNNEL-UUID>`
    143    - `credentials-file: C:\\Users\\<you>\\.cloudflared\\<TUNNEL-UUID>.json`
    144    - `ingress:` mapping your hostname to Bzl:
    145      - `- hostname: bzl.yourdomain.com`
    146        `service: http://localhost:3000`
    147      - `- service: http_status:404`
    148 6. Run it:
    149    - Foreground: `cloudflared tunnel run bzl` (requires the `config.yml` ingress rules)
    150    - One-off (no config): `cloudflared tunnel run bzl --url http://localhost:3000`
    151    - As a service: `cloudflared service install` (then it starts on boot)
    152 
    153 ## Environment variables
    154 
    155 - `PORT` (default `3000`)
    156 - `HOST` (default `0.0.0.0`)
    157 - `DEFAULT_TTL_MS` (default `3600000`)
    158 - `MIN_TTL_MS` (default `60000`)
    159 - `MAX_TTL_MS` (default `172800000`)
    160 - `USERS_FILE` (default `data/users.json`)
    161 - `POSTS_FILE` (default `data/posts.json`)
    162 - `COLLECTIONS_FILE` (default `data/collections.json`)
    163 - `ROLES_FILE` (default `data/roles.json`)
    164 - `UPLOADS_DIR` (default `data/uploads`)
    165 - `IMAGE_UPLOAD_MAX_BYTES` (default `104857600` = 100 MB)
    166 - `AUDIO_UPLOAD_MAX_BYTES` (default `157286400` = 150 MB)
    167 - `PROFILE_BIO_MAX_HTML_LEN` (default `120000`)
    168 - `PROFILE_PRONOUNS_MAX_LEN` (default `40`)
    169 - `PROFILE_LINK_LABEL_MAX_LEN` (default `40`)
    170 - `PROFILE_LINK_URL_MAX_LEN` (default `280`)
    171 - `PROFILE_LINKS_MAX` (default `8`)
    172 
    173 Startup validation:
    174 - Server validates critical env values at boot and exits with clear errors if invalid.
    175 
    176 Rate limits:
    177 - Auth: login/register/resume session are rate-limited.
    178 - Uploads: image/audio uploads are rate-limited per sender.
    179 - Moderation: report creation and moderation actions are rate-limited.
    180 - Server emits `rateLimited` messages over WebSocket and `429` with `retryMs` for upload API.
    181 
    182 Rate limit env vars:
    183 - `RL_LOGIN_WINDOW_MS` (default `60000`)
    184 - `RL_LOGIN_MAX` (default `12`)
    185 - `RL_REGISTER_WINDOW_MS` (default `600000`)
    186 - `RL_REGISTER_MAX` (default `6`)
    187 - `RL_RESUME_WINDOW_MS` (default `60000`)
    188 - `RL_RESUME_MAX` (default `30`)
    189 - `RL_UPLOAD_WINDOW_MS` (default `300000`)
    190 - `RL_UPLOAD_IMAGE_MAX` (default `20`)
    191 - `RL_UPLOAD_AUDIO_MAX` (default `10`)
    192 - `RL_REPORT_WINDOW_MS` (default `600000`)
    193 - `RL_REPORT_MAX` (default `12`)
    194 - `RL_MOD_WINDOW_MS` (default `60000`)
    195 - `RL_MOD_MAX` (default `40`)
    196 
    197 ## Open source
    198 
    199 Bzl is released under the MIT License. See `LICENSE`.
    200 
    201 Community docs:
    202 - Contributing: `CONTRIBUTING.md`
    203 - Security policy: `SECURITY.md`
    204 - Issue tracker guide: `docs/ISSUE_TRACKER.md`