Unified chat infrastructure for All Things Linux: IRC, XMPP, web, and protocol bridges.
Monorepo layout:
apps/
├── unrealircd/ # UnrealIRCd 6.x server
├── atheme/ # IRC services (NickServ, ChanServ, OperServ, MemoServ)
├── webpanel/ # UnrealIRCd web admin
├── prosody/ # XMPP server
├── web/ # Next.js web application
├── bridge/ # Discord↔IRC↔XMPP bridge (Python, in-repo)
├── thelounge/ # Web IRC client (private mode, WebIRC)
├── obsidianirc/ # Modern IRC web client (custom build)
├── fluux-messenger/ # Fluux XMPP web client (React + Vite, nginx)
├── gamja/ # IRC web client (planned)
└── docs/ # Fumadocs documentation site
Compose fragments in infra/compose/:
irc.yaml— UnrealIRCd, Atheme, WebPanelxmpp.yaml— Prosodycert-manager.yaml— Lego (Let's Encrypt)bridge.yaml— Discord↔IRC↔XMPP bridgethelounge.yaml— The Lounge web IRC clientobsidianirc.yaml— ObsidianIRC web clientfluux-messenger.yaml— Fluux XMPP web clientnetworks.yaml— Sharedatl-chatnetwork
- Docker & Docker Compose
- just — task runner
- Node.js 20+ & pnpm 9+ — for web app (optional)
- uv or Python 3.11+ — for tests (optional)
git clone https://github.com/allthingslinux/atl.chat.git
cd atl.chat
cp .env.example .env
# Edit .env with your domains, passwords, and TLS paths
# For dev (localhost domains): create overlay from .env.dev.example
cp .env.dev.example .env.dev
just init # Creates data/ dirs, generates config, dev certs
just dev # Starts stack with dev profile (Dozzle, localhost domains)just init runs scripts/init.sh and scripts/prepare-config.sh to:
- Create
data/irc/,data/atheme/,data/xmpp/,data/thelounge/,data/obsidianirc/,data/certs/ - Substitute
.envinto UnrealIRCd, Atheme, and Bridge config templates - Generate dev certs for
irc.localhost(if missing)
just dev requires .env.dev (copy from .env.dev.example); it overrides domains for localhost.
# Development (localhost domains, Dozzle for logs)
just dev
# Production (uses domains from .env)
just prodWhen using the bridge with Portal for identity resolution, use the same secret for both: set BRIDGE_PORTAL_TOKEN (atl.chat) and BRIDGE_SERVICE_TOKEN (Portal) to the same value.
After starting the production stack for the first time, you must manually bootstrap the Services Root Administrator (SRA) to avoid being locked out of IRC services:
- Connect to IRC using your admin account.
- In the terminal, run:
just irc sra-bootstrap <your_nick> - OperServ will then recognize you as a network administrator.
| Service | Container | Ports |
|---|---|---|
| UnrealIRCd | atl-irc-server |
6697 (TLS), 6900 (server), 8600 (RPC), 8000 (WebSocket) |
| Atheme | atl-irc-services |
6901 (uplink), 8081 (HTTPd) |
| WebPanel | atl-irc-webpanel |
8080 |
Tasks:
just irc shell # Bash into IRC server
just irc reload # Reload UnrealIRCd config
just logs # Follow logs (root command; use service name to filter)See docs-old/services/irc/ for full docs.
| Port | Purpose |
|---|---|
| 5222 | C2S (client) |
| 5223 | C2S Direct TLS |
| 5269 | S2S |
| 5270 | S2S Direct TLS |
| 5280 | HTTP/BOSH |
| 5281 | HTTPS |
| 5000 | Proxy65 (file transfer) |
Tasks:
just xmpp shell # Bash into Prosody
just xmpp reload # Reload Prosody
just xmpp adduser # Add XMPP userNext.js 14 app (port 3000):
just web dev
# or: cd apps/web && pnpm devDiscord↔IRC↔XMPP bridge (Python, in-repo). Multi-presence puppeting, IR-based format conversion, Portal identity integration. Config generated from apps/bridge/config.template.yaml by just init. See apps/bridge/ and infra/compose/bridge.yaml.
just bridge test # Run bridge tests
just bridge lint # Ruff check
just bridge format # Ruff format
just bridge typecheck # Basedpyright
just bridge check # Full check (lint + format + typecheck + test)Web IRC client (private mode, WebIRC). See apps/thelounge/.
just lounge add <name> # Create user (prompts for password)
just lounge list # List users
just lounge reset <name> # Reset user passwordModern IRC web client (custom build). See apps/obsidianirc/.
just obsidianirc rebuild # Rebuild image
just obsidianirc rebuild-clean # Rebuild without cacheReact + Vite XMPP web client by ProcessOne, served via nginx. Connects to Prosody via WebSocket. See apps/fluux-messenger/.
| Port | Purpose |
|---|---|
| 8091 | HTTP |
| 8443 | HTTPS |
just --list # All tasks
# Orchestration
just init # One-time setup
just dev # Start dev stack
just prod # Start prod stack
just down # Stop dev stack
just down-prod # Stop prod stack
just logs [svc] # Follow logs (optionally for a service)
just status # Container status
# Build & test
just build # Build images
just test # Run root pytest
just test-all # Root tests + bridge tests
just lint # pre-commit run --all-files
just scan # Security scans (Gitleaks, Trivy)
just clean # Prune unused Docker resources
just prosody-token # Generate Prosody admin API Bearer tokenAll persistent data lives under data/:
data/
├── irc/
│ ├── data/ # UnrealIRCd runtime
│ ├── logs/ # UnrealIRCd logs
│ └── webpanel-data/ # Web panel state
├── atheme/
│ ├── data/ # services.db
│ └── logs/ # atheme.log
├── xmpp/
│ ├── data/ # Prosody SQLite
│ ├── logs/ # Prosody logs
│ └── uploads/ # File uploads
├── thelounge/ # The Lounge user data
├── obsidianirc/ # ObsidianIRC data (if needed)
└── certs/ # TLS certs (Let's Encrypt layout)
└── live/<domain>/ # fullchain.pem, privkey.pem
See docs-old/infra/data-structure.md.
Single .env at repo root. Copy from .env.example and customize. For dev, also create .env.dev from .env.dev.example.
cp .env.example .envKey groups:
- IRC:
IRC_DOMAIN,IRC_NETWORK_NAME,IRC_OPER_PASSWORD, cloak keys - TLS:
IRC_SSL_CERT_PATH,IRC_SSL_KEY_PATH(paths inside container) - Atheme:
ATHEME_SEND_PASSWORD,ATHEME_RECEIVE_PASSWORD,IRC_SERVICES_PASSWORD - XMPP:
PROSODY_DOMAIN,PROSODY_SSL_*
Config is generated via scripts/prepare-config.sh (run by just init). After editing .env, rerun:
./scripts/prepare-config.sh| Profile | Use case |
|---|---|
| default | Production-style (domains from .env) |
| dev | Dozzle, localhost domains, extra tools |
| prod | Production |
docker compose --profile dev up -d
just dev # Uses .env.dev + dev profile| Area | Path |
|---|---|
| Hub | docs-old/README.md |
| Onboarding | docs-old/onboarding/README.md |
| Architecture | docs-old/architecture/README.md |
| Data layout | docs-old/infra/data-structure.md |
| IRC | docs-old/services/irc/ |
| XMPP | docs-old/services/xmpp/ |
| Web | docs-old/services/web/ |
| Bridges | docs-old/bridges/README.md |
| Fumadocs Site | apps/docs/ |
GitHub Actions runs on push to main/develop and on pull requests:
- Path-based change detection (only affected services are checked)
- Lint, test, and Docker build jobs per service (IRC, XMPP, Web, Bridge)
- Security scans (Gitleaks, Trivy)
- Semantic versioning with automatic changelog on
mainvia semantic-release
See CONTRIBUTING.md for setup instructions, commit conventions, and code style guidelines.
Apache 2.0 — see LICENSE.