The bridge is a single Docker container that runs as uid/gid 1000:1000, exposes a web UI on port 4567, and persists everything to SQLite under /app/state. Any host that can run a Docker container 24/7 will work.
- Docker (any reasonably recent release).
- A persistent host directory for the SQLite database. Anything you control is fine:
./state,/var/lib/reddit_chat_bridge, your NAS appdata share, etc. - A way to reach port 4567 from your browser. LAN, Tailscale, a reverse proxy, an SSH tunnel — your call. The bridge does not do its own TLS termination.
mkdir -p ./state
sudo chown 1000:1000 ./state
docker run -d \
--name reddit_chat_bridge \
--restart unless-stopped \
--user 1000:1000 \
-p 4567:4567 \
-v "$PWD/state:/app/state" \
ghcr.io/mmenanno/reddit_chat_bridge:latestThe chown matters: the container runs as uid/gid 1000:1000, and SQLite needs to be able to write to the volume. If the host directory is owned by another user, you'll see permission errors in docker logs.
The repo ships a working docker-compose.yml at the root. Either copy it next to your other compose files, or clone the repo and run it in place:
mkdir -p ./state
sudo chown 1000:1000 ./state
docker compose up -dTail the logs to confirm boot:
docker compose logs -f reddit_chat_bridgeHealth is reported via Docker's healthcheck (/health on port 4567). docker ps shows (healthy) once Puma is up and the database is queryable.
-
Open
http://<your-host>:4567/. First load lands on/setup. -
Create the admin account (12+ character password).
-
The wizard at
/guide/bot-setupwalks through Discord application creation, builds an invite URL with the right permissions baked in, and live-tracks which configuration fields are still missing. Save when it goes green. -
On
/auth, paste yourreddit_sessioncookie (preferred, ~6 month lifetime) or a fresh Matrix JWT (short-lived, ~24h fallback). The drag-to-bookmark helper on/authgrabs a JWT from any logged-in reddit.com tab without DevTools. Probe and save. -
Restart the container once so the supervisor picks up the now-complete config and starts the background sync thread:
docker restart reddit_chat_bridge # or docker compose restart reddit_chat_bridgeSubsequent settings or token changes take effect live; only the first boot needs this.
The :latest tag is republished on every push to main after CI passes. Pull and recreate:
docker compose pull
docker compose up -dThe state/ volume survives the recreation; the SQLite database (with all your settings, room links, dedup state, and encrypted Reddit cookies) is preserved.
The CI workflow tags every release as :v<version> (read from the VERSION file) and :sha-<short>. To pin, set the image: line in your compose file or docker run to the specific tag:
image: ghcr.io/mmenanno/reddit_chat_bridge:v1.11.0Useful when a :latest rollout misbehaves and you want to roll back without waiting for a fix.
The bridge ships only the web port; how you expose it is up to you. A few patterns that work:
- Local network only.
docker run -p 4567:4567and access viahttp://<host-lan-ip>:4567/from your LAN. Don't do this on a publicly-routable host. - Tailscale sidecar. Add a Tailscale or Headscale container alongside the bridge, or run the host on Tailscale and access via the host's tailnet hostname.
- Reverse proxy (Traefik / Caddy / nginx). Put the bridge on a Docker network shared with your reverse proxy and route a hostname to
reddit_chat_bridge:4567. Caddy automation handles TLS automatically.
The bridge has no built-in auth proxy or IP allow-list, so don't expose it raw to the public internet. The admin login (/login) is bcrypt-protected, but it's a single-account login form — keep it on a trusted network.
| Env var | Default | Notes |
|---|---|---|
PORT |
4567 |
Web UI bind port. |
RACK_ENV |
production |
Don't override for production. |
SESSION_SECRET |
auto-generated | Optional. If unset, a value is generated on first boot and persisted in the database. |
Everything else (Discord bot token, application ID, guild ID, channel IDs, operator user IDs, Reddit auth) lives in the SQLite database and is edited through the web UI.
(unhealthy)indocker ps— checkdocker logsfor Ruby-level errors. Common causes: bad volume permissions (chown to1000:1000), corrupt database, port collision.- Web UI loads but says "no Matrix connection" — expected before
/authhas been completed. Finish the first-run setup. - Permission errors writing to
/app/state—sudo chown -R 1000:1000 <your-state-dir>and recreate the container. - Reddit auth keeps failing — the cookie may have expired or been invalidated by Reddit (logging out anywhere triggers this). Grab a fresh
reddit_sessioncookie from a logged-in browser tab and paste it on/auth. - Discord posts aren't appearing — check
/settingsfor the right channel IDs, verify the bot is in the server, and confirm the role has the permissions the wizard listed (Manage Channels, Manage Webhooks, Manage Messages, Send Messages, Embed Links, Read Message History, Use Slash Commands).
Unraid containers should be created via the Unraid web UI (Docker → Add Container) so the template XML is the source of truth, but everything else in this guide applies. The mappings to set:
- Repository:
ghcr.io/mmenanno/reddit_chat_bridge:latest - Path: Container
/app/state→ Host/mnt/user/appdata/reddit_chat_bridge(or wherever your appdata lives) - Port: Container
4567→ Host4567(optional if you reach the container via a proxy on the same Docker network) - uid/gid: the container runs as
1000:1000. Chown the appdata dir to match before the first start, or you'll see SQLite write errors.