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 (in-repo)
├── thelounge/ # Web IRC client (private mode, WebIRC)
└── gamja/ # IRC web client (planned)
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 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/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 prodAfter 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/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 userSee docs/services/xmpp/.
Next.js 14 app (port 3000):
just web dev
# or: cd apps/web && pnpm devDiscord↔IRC↔XMPP bridge (in-repo). 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 passwordjust --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 resourcesAll 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
└── certs/ # TLS certs (Let's Encrypt layout)
└── live/<domain>/ # fullchain.pem, privkey.pem
See docs/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/README.md |
| Onboarding | docs/onboarding/README.md |
| Architecture | docs/architecture/README.md |
| Data layout | docs/infra/data-structure.md |
| IRC | docs/services/irc/ |
| XMPP | docs/services/xmpp/ |
| Web | docs/services/web/ |
| Bridges | docs/bridges/README.md |
- Fork and branch:
git checkout -b feat/my-feature - Run
just initandjust dev - Make changes
- Run
just test-allandjust lint - Commit:
git commit -m "feat: add feature"(conventional commits) - Open a pull request
See LICENSE.