guide · getting started

Get Chirkle running.

Chirkle is an npm package. It brings the web app with it and downloads PocketBase on the first run, so there's nothing to clone and nothing to build. Try it on your own machine in a minute, then put it on a server with HTTPS when you're ready.

before you start

What you need

  • Node.js 22 or newer and npm 11 or newer. Check with node -v and npm -v.
  • Linux or macOS, on x64 or arm64. On Windows, use WSL or the Docker image.
  • Optional: ffmpeg and curl on the PATH, for video thumbnails and link previews. Chirkle runs fine without them.
  • For a public server: a VPS (1 CPU and 1 GB of RAM is plenty) and a domain you can point at it.

part 1 · on your machine

Run it locally

  1. Start the server. Run this in any folder. Chirkle keeps its data in a pb_data folder inside the folder you run it from.
    $ npx chirkle
      → http://127.0.0.1:8090
  2. Sign up. Open http://127.0.0.1:8090 and create an account. The first rooms are yours to make.
  3. Create an admin account. The first run prints a link that creates one. Or, in a second terminal in the same folder:
    $ npx chirkle superuser upsert you@example.com <password>
    Then sign in to the admin UI at http://127.0.0.1:8090/_/. That's where every setting below lives.

Options

  • Keep data somewhere else: set CHIRKLE_DATA=/path/to/data.
  • Use another port: set PORT=3000.
  • Open it to other devices on your network, for example to try the Android app on your phone: set HOST=0.0.0.0 and use your computer's local IP address.
  • Pass PocketBase flags: any pocketbase serve flag works, for example npx chirkle --http=0.0.0.0:80.
  • Start over: stop the server and delete the pb_data folder.
$ HOST=0.0.0.0 PORT=3000 CHIRKLE_DATA=~/chirkle-data npx chirkle

From source

If you want to change Chirkle itself, clone the repository and run the dev server. It rebuilds the web app as you edit.

$ git clone https://github.com/border-radius/chirkle
$ cd chirkle
$ npm ci
$ npm run setup   # downloads a checksum-verified PocketBase into bin/
$ npm run dev     # → http://127.0.0.1:8090

part 2 · on a server

Run it on a server

Give Chirkle a domain and it serves HTTPS on its own, with a certificate from Let's Encrypt. No nginx or Caddy needed.

Quick start

  1. Point your domain at the server. Add an A record (and AAAA for IPv6) for, say, chat.example.com with your server's IP. Make sure ports 80 and 443 are open.
  2. Start Chirkle with the domain. It needs to bind ports 80 and 443, so run it as root or give Node that capability.
    $ npx chirkle chat.example.com
    The first request to https://chat.example.com fetches the certificate.
  3. Create your admin account, then sign in to the admin UI at https://chat.example.com/_/.
    $ npx chirkle superuser upsert you@example.com <password>

Keep it running with systemd

For a server that starts on boot and restarts if it crashes, install Chirkle into its own folder under a dedicated user.

$ sudo useradd --system --create-home --home-dir /opt/chirkle chirkle
$ sudo -u chirkle sh -c 'cd /opt/chirkle && npm install chirkle'

Then create /etc/systemd/system/chirkle.service:

[Unit]
Description=Chirkle
After=network-online.target

[Service]
User=chirkle
WorkingDirectory=/opt/chirkle
ExecStart=/opt/chirkle/node_modules/.bin/chirkle chat.example.com
Restart=on-failure
AmbientCapabilities=CAP_NET_BIND_SERVICE
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
$ sudo systemctl enable --now chirkle
$ sudo -u chirkle sh -c 'cd /opt/chirkle && node_modules/.bin/chirkle superuser upsert you@example.com <password>'
$ journalctl -u chirkle -f   # logs

Data lives in /opt/chirkle/pb_data. Environment variables for the features below go in the [Service] block as Environment=KEY=value lines.

Update

$ sudo -u chirkle sh -c 'cd /opt/chirkle && npm install chirkle@latest'
$ sudo systemctl restart chirkle

Database migrations run automatically on start. Take a backup first (see Backups).

Behind a reverse proxy

If nginx, Caddy or another proxy already owns ports 80 and 443, run Chirkle on a local port and proxy to it:

$ TRUSTED_PROXY=X-Forwarded-For npx chirkle   # listens on 127.0.0.1:8090
  • Don't buffer /api/realtime. It's a server-sent events stream that carries live messages.
  • Allow request bodies up to 210 MB. A message can carry 10 files of 20 MB each.
  • Set TRUSTED_PROXY=X-Forwarded-For so rate limits apply to each visitor instead of to the proxy.

With Docker

The repository's Dockerfile builds an image with the web app, PocketBase, ffmpeg and curl. It listens on port 8090, so put a reverse proxy in front for HTTPS (see above).

$ git clone https://github.com/border-radius/chirkle && cd chirkle
$ docker build -t chirkle .
$ docker run -d --name chirkle --restart unless-stopped \
    -p 127.0.0.1:8090:8090 -v chirkle-data:/pb_data chirkle
$ docker exec chirkle /app/pocketbase superuser upsert you@example.com <password> --dir=/pb_data

All data lives in the /pb_data volume. The image trusts X-Forwarded-For from a proxy; if clients reach port 8090 directly, add -e TRUSTED_PROXY=off.

With Dokku

Dokku builds the same image from the Dockerfile. On the Dokku host:

$ dokku apps:create chirkle
$ dokku storage:ensure-directory chirkle
$ dokku storage:mount chirkle /var/lib/dokku/data/storage/chirkle:/pb_data
$ dokku domains:set chirkle chat.example.com
$ dokku nginx:set chirkle client-max-body-size 210m
$ dokku letsencrypt:enable chirkle   # needs the dokku-letsencrypt plugin

Then, from a clone of the repository:

$ git remote add dokku dokku@server:chirkle
$ git push dokku master
$ dokku run chirkle /app/pocketbase superuser upsert you@example.com <password> --dir=/pb_data

Set environment variables with dokku config:set chirkle KEY=value, which restarts the app. Follow logs with dokku logs chirkle -t.

part 3 · features

Turn on features

Most settings live in the admin UI at /_/. A few are environment variables, which take effect after a restart.

Your name and logo

Open Collections → site, edit its one record and set title and logo. They show in the app bar, on the login page and in the browser tab.

Invite-only signups

  1. Require a code. On the same site record, tick invite_only and set invite_code. Codes are case-sensitive.
  2. Share it. Send the code to the people you want to let in. They enter it on the sign-up form.
  • To revoke a code, change it. People who already signed up keep their accounts.
  • To close signups completely, clear invite_code while invite_only stays ticked.
  • You can always create accounts yourself under Collections → users.

Backups

Open Settings → Backups to make a backup now or schedule them, for example nightly. Backups can go to any S3-compatible storage (AWS, Backblaze B2, Cloudflare R2, MinIO and others). Backups include uploaded files (avatars and attachments), so plan disk space for them.

Store files on S3

Uploaded files are kept in pb_data/storage by default. To keep them on S3-compatible storage instead, fill in Settings → Files storage.

Moderators

Moderators can delete any message, change any public room's access, archive rooms and ban accounts. To make someone a moderator, open Collections → users, edit their record and tick moderator.

Rate limits

Chirkle ships with defaults such as 10 messages per 5 seconds per IP, 5 new rooms per minute and 20 signups per minute. Adjust them under Settings → Rate limits.

Link previews and video thumbnails

Both are on by default. Link previews show a site's icon and title under each link; the server fetches them with curl, from public addresses only. Video poster frames, shown in rooms and the media grid, are made with ffmpeg. Both tools are in the Docker image; elsewhere, install them on the server or the feature quietly does without. To turn them off on purpose:

LINK_PREVIEWS=off
FFMPEG=off

Android app

  • Connect to your server. Install the APK, tap Change server when you sign in and enter your server's https:// address. Add more accounts, on any server, from your profile. Notifications work with nothing to set up on the server.
  • Open room links in the app. If you build the app for your own server, set ANDROID_CERT_SHA256 to its signing certificate fingerprint, and ANDROID_APP_ID if you changed its app ID. See the README for building.
  • Ask old versions to update. Set min_android_version on the site record.

Linked servers and Telegram

Your server can share rooms and DMs with other Chirkle servers, and bridge rooms to Telegram groups through your own bot. Both are off by default. See Linking servers and bridging Telegram for the setup.

more detail

Every option and how it works is covered in the README and the project's design notes. Questions and bug reports go to GitHub issues.