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 prod
When 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 user
Next.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 password
Modern IRC web client (custom build). See apps/obsidianirc/.
just obsidianirc rebuild # Rebuild image just obsidianirc rebuild-clean # Rebuild without cache
React + 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 token
All 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 .env
Key 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.