Messages room info to a private chat network. Everyone subscribed gets the link.
70
Open a room on a chat network, and everyone who subscribed on any chat network gets a way into it. Supports Tor, I2P, Reticulum party lines, and WebRTC browser links. Fans credentials to nine chat networks. No database, no accounts, nothing remembered.
This is the daemon-only image: one container per network/transport you enable, no ttyd, no bundled wizard, no port 7681.
There is no separate "wizard edition" of this image.
The setup wizard (partylinepager.sh) is a script in the git repo, you can download.
It runs on your host, writes .env, policy.toml and adapters.toml for you, and then calls docker compose to pull and run this exact image.
| Architecture | Tag |
|---|---|
| x86-64 | amd64 |
git clone https://github.com/MarcusHoltz/partylinepager.git && cd partylinepager
./partylinepager.sh
For scripted or config-management deployments where you'd rather not clone
the whole repo. Requires a policy.toml and adapters.toml already sitting
in ./config, written against the config reference.
Save as docker-compose.yml, then run docker compose up -d:
services:
partylinepagerd:
image: marcusholtz/partylinepager:latest
container_name: partylinepagerd
restart: unless-stopped
user: "1000:1000"
volumes:
- ./config:/etc/partylinepager
environment:
- RUST_LOG=info
- TELEGRAM_TOKEN=your-bot-token
command: ["--state", "/etc/partylinepager/state"]
docker run -d \
--name partylinepagerd \
--restart unless-stopped \
--user 1000:1000 \
-v ./config:/etc/partylinepager \
-e RUST_LOG=info \
-e TELEGRAM_TOKEN=your-bot-token \
marcusholtz/partylinepager:latest \
--state /etc/partylinepager/state
policy.toml and adapters.toml are already in ./config (see above)--user matches your host uid:gid, or ./config/state ends up root-owned[enabled = true] in adapters.tomldocker compose run --rm partylinepagerd --check validates config before starting anythingdocker compose up -d starts the daemonNo web terminal, no port to publish. Administration is docker compose exec only, same as any headless deployment.
docker compose exec partylinepagerd partylinepagerctl who
docker compose exec partylinepagerd partylinepagerctl approve telegram:123456789
| Parameter | Function |
|---|---|
-v /etc/partylinepager | policy.toml and adapters.toml (read by the daemon), plus state/ (roster and room state, auto-created) |
--state /etc/partylinepager/state | Command argument, not an env var: where state is written inside the mount |
-e RUST_LOG=info | Log verbosity |
--user 1000:1000 | Match your host uid:gid so ./config/state isn't written as root |
Enable an adapter by setting enabled = true under its section in adapters.toml, then pass the matching secret through -e. Only adapters you pass a secret for receive room notifications.
| Parameter | Function |
|---|---|
-e TELEGRAM_TOKEN | Bot token from @BotFather ([telegram]) |
-e MATRIX_PASSWORD | Matrix bot account password ([matrix]) |
-e IRC_PASSWORD | NickServ password for SASL PLAIN ([irc]); omit to connect without logging in |
-e XMPP_PASSWORD | XMPP account password ([xmpp]) |
-e MASTODON_TOKEN | Mastodon application token ([mastodon]) |
-e IMAP_PASSWORD | IMAP account password ([email]) |
-e SMTP_PASSWORD | SMTP account password ([email]) |
-e MATTERMOST_TOKEN | Personal or bot access token ([mattermost]) |
-e DISCORD_TOKEN | Bot token from the Discord Developer Portal ([discord]) |
Signal ([signal]) takes no token here: it needs a second container, bbernhard/signal-cli-rest-api, linked or registered separately and mounted at /home/.local/share/signal-cli. Apprise (apprise: endpoints, added at runtime, not in adapters.toml) needs caronc/apprise as a stateless sidecar.
Off by default. Turning one on in policy.toml ([provider.tor], [provider.i2p], [provider.rns]) means this container also needs the Docker socket, because the provider hooks bring the transport up and down as its own container.
| Parameter | Function |
|---|---|
-v /var/run/docker.sock | Only if any [provider.*] party line is enabled |
-e DOCKER_GID | The docker group's gid on the host (getent group docker | cut -d: -f3), passed to group_add |
-v <transport-dir> | Bind-mounted at the identical path inside and outside the container; holds the transport's own compose file, pulls a published relay image, no checkout needed |
[provider.web] needs neither. If you're only running web rooms, leave the socket out entirely: docker compose config | grep -c docker.sock should print 0.
A subscriber sends a command (partyline or web) on any connected chat network. The engine:
One room at a time. No occupancy tracking, no catch-up, no record of who joined.
# Config check before ever starting the daemon
docker compose run --rm partylinepagerd --check
# Logs: look for "ok" from the check, then normal startup
docker compose logs partylinepagerd
# Roster check
docker compose exec partylinepagerd partylinepagerctl who
Three transports, same encryption, same TUI:
PartylinePager orchestrates all three (plus WebRTC) and fans credentials across nine chat networks.
MIT
Content type
Image
Digest
sha256:75d66ba1d…
Size
97.6 MB
Last updated
about 15 hours ago
docker pull marcusholtz/partylinepager