Documentation Index
Fetch the complete documentation index at: https://docs.allthingslinux.org/llms.txt
Use this file to discover all available pages before exploring further.
Values are loaded from .env (copy from .env.example) and optional overlays .env.dev / .env.prod. The root script scripts/prepare-config.sh substitutes ${VAR} into UnrealIRCd, Atheme, bridge, and The Lounge templates.
This page documents variables used by this monorepo. The external ATL Portal uses its own env (see that repo’s docs/ENV_VARS.md); bridge auth uses BRIDGE_PORTAL_TOKEN here and BRIDGE_SERVICE_TOKEN on the portal — they must match when Portal identity is enabled.
How environment files work
.env — baseline; copy from .env.example.
.env.dev — dev overlay for just dev (from .env.dev.example).
.env.prod — production-only overrides for just prod.
cp .env.example .env
cp .env.dev.example .env.dev
just dev
Compose merges .env then the overlay. apps/docs deploy (Alchemy / Workers) uses separate vars — see Docs (deployment) below; those are not in the root .env.example.
Core
| Variable | Description | Required | Default (.env.example) |
|---|
PUID | Container UID for volume ownership | No | 1000 |
PGID | Container GID for volume ownership | No | 1000 |
TZ | Timezone | No | UTC |
ATL_GATEWAY_IP | Address used in UnrealIRCd WebIRC match { ip … } blocks | Yes | 127.0.0.1 (use Tailscale or gateway IP in prod) |
ATL_CHAT_IP | Host IP Compose binds IRC/XMPP ports to | Yes | 127.0.0.1 |
LETSENCRYPT_EMAIL | ACME registration email (cert-manager) | For LE | admin@allthingslinux.org |
CLOUDFLARE_DNS_API_TOKEN | DNS-01 API token (cert-manager) | Prod LE | (empty) |
LOG_MAX_SIZE | Docker json-file max size per log file | No | 50m |
LOG_MAX_FILES | Rotated log files to keep per container | No | 5 |
Warning: CLOUDFLARE_DNS_API_TOKEN is highly sensitive. In local dev it is often unset; Compose may warn — safe to ignore if you are not issuing certs.
TLS and IRC client behaviour (explicit flags)
These are set in .env.example so dev/prod behaviour does not depend on a single ATL_ENVIRONMENT variable. scripts/prepare-config.sh uses BRIDGE_IRC_TLS_VERIFY (if set) when exporting IRC_TLS_VERIFY for UnrealIRCd-related substitution.
| Variable | Description | Default (.env.example) |
|---|
IRC_TLS_VERIFY | Verify TLS when connecting to IRC (e.g. bridge → IRC) | false |
IRC_LOUNGE_REJECT_UNAUTHORIZED | Node TLS rejectUnauthorized for The Lounge → IRC | false |
IRC_WEBSOCKET_USE_TLS | Enable TLS on UnrealIRCd listener in generated config | true |
BRIDGE_IRC_TLS_VERIFY | Passed to the bridge container; prefer this for bridge-specific TLS | false |
IRC Service (UnrealIRCd + Atheme)
Build versions
| Variable | Description | Required | Default (.env.example) |
|---|
UNREALIRCD_VERSION | UnrealIRCd image tag | Yes | 6.2.0.1 |
ATHEME_VERSION | Atheme image tag | Yes | master |
Warning: ATHEME_VERSION=master is non-reproducible. Pin for production.
Network identity
| Variable | Description | Required | Default (.env.example) |
|---|
IRC_DOMAIN | Public IRC hostname (TLS/SNI, cert paths) | Yes | irc.localhost (prod: e.g. irc.atl.chat) |
IRC_ROOT_DOMAIN | Network root domain | Yes | atl.chat |
IRC_NETWORK_NAME | Human-readable network name | Yes | All Things Linux IRC |
IRC_CLOAK_PREFIX | Cloak prefix | Yes | atl |
Ports
| Variable | Description | Required | Default |
|---|
IRC_TLS_PORT | TLS client port | Yes | 6697 |
IRC_SERVER_PORT | Server link port | Yes | 6900 |
IRC_RPC_PORT | JSON-RPC port | Yes | 8600 |
IRC_WEBSOCKET_PORT | WebSocket port | Yes | 8000 |
Security secrets
| Variable | Description | Required | Default (.env.example) |
|---|
IRC_CLOAK_KEY_1 … IRC_CLOAK_KEY_3 | Cloak keys (same on all linked servers) | Yes | replace_with_cloak_key_* |
IRC_OPER_PASSWORD | IRC oper password | Yes | change_me_irc_oper_password |
IRC_DRPASS | UnrealIRCd die/restart password | Yes | change_me_drpass |
IRC_SERVICES_PASSWORD | UnrealIRCd ↔ Atheme link password | Yes | change_me_irc_services_password |
ATL_WEBIRC_PASSWORD | WebIRC shared secret (UnrealIRCd + clients) | Yes | change_me_webirc_password |
Warning: Replace all placeholders before any public deployment. just irc gencloak for cloak keys; hashed oper passwords: docker run --rm ghcr.io/allthingslinux/unrealircd ./unrealircd mkpasswd argon2 <password>.
Admin info
| Variable | Description | Required | Default |
|---|
IRC_ADMIN_NAME | Shown in /admin | Yes | All Things Linux |
IRC_ADMIN_EMAIL | Admin contact | Yes | admin@allthingslinux.org |
IRC_STAFF_VHOST | Staff vhost | No | allthingslinux.org |
Strict Transport Security (STS)
| Variable | Description | Default |
|---|
IRC_STS_DURATION | STS duration | 1m |
IRC_STS_PRELOAD | STS preload | no |
TLS certificate paths (inside UnrealIRCd container)
| Variable | Description | Default (.env.example) |
|---|
IRC_SSL_CERT_PATH | Fullchain path | …/certs/live/irc.localhost/fullchain.pem |
IRC_SSL_KEY_PATH | Private key path | …/certs/live/irc.localhost/privkey.pem |
Warning: Never commit private keys.
Atheme (reduced env surface)
.env.example only exposes the variables substituted into apps/atheme/config/atheme.conf.template. Service bot nicks/users/hosts are hardcoded in that template (or commented for optional modules) — they are not per-bot env vars in the current layout.
| Variable | Description | Default (.env.example) |
|---|
IRC_SERVICES_SERVER | UnrealIRCd link services.* target hostname | Optional; default in prepare-config is ATHEME_SERVER_NAME or services.${IRC_ROOT_DOMAIN} |
ATHEME_SERVER_NAME | Services server name on the network | services.atl.chat |
ATHEME_SERVER_DESC | Server description | All Things Linux IRC Services |
ATHEME_UPLINK_HOST | UnrealIRCd hostname from Atheme container | 127.0.0.1 |
ATHEME_UPLINK_PORT | UnrealIRCd listen port for services | 6901 |
ATHEME_NUMERIC | Server numeric | 00A |
ATHEME_RECONTIME | Reconnect interval (seconds) | 10 |
ATHEME_HTTPD_PORT | JSON-RPC HTTP port | 8081 |
ATHEME_NETNAME | Network name in Atheme | atl.chat |
ATHEME_HIDEHOST_SUFFIX | Hidden-host suffix | users.atl.chat |
ATHEME_ADMIN_NAME | Admin display name | All Things Linux |
ATHEME_ADMIN_EMAIL | Admin email in config | admin@allthingslinux.org |
ATHEME_REGISTER_EMAIL | Registration mail from-address | noreply@allthingslinux.org |
ATHEME_SRA_BOOTSTRAP_ACCOUNT | Nick granted SRA on first DB init | admin |
ATHEME_HELP_CHANNEL | Help channel | #help |
ATHEME_HELP_URL | Help URL | https://allthingslinux.org |
Atheme service bot identities (template defaults)
The live apps/atheme/config/atheme.conf.template hardcodes nicks, users, hosts, and realnames for each service bot (NickServ, ChanServ, etc.). They are not exposed as ATHEME_* env vars in .env.example. If you fork the template, each bot follows the pattern ATHEME_<SERVICE>_NICK, _USER, _HOST, _REAL.
| Service | Nick | User | Host | Real name |
|---|
| NickServ | NickServ | NickServ | services.atl.chat | Nickname Services |
| ChanServ | ChanServ | ChanServ | services.atl.chat | Channel Services |
| OperServ | OperServ | OperServ | services.atl.chat | Operator Services |
| MemoServ | MemoServ | MemoServ | services.atl.chat | Memo Services |
| SaslServ | SaslServ | SaslServ | services.atl.chat | SASL Authentication Agent |
| BotServ | BotServ | BotServ | services.atl.chat | Bot Services |
| GroupServ | GroupServ | GroupServ | services.atl.chat | Group Management Services |
| HostServ | HostServ | HostServ | services.atl.chat | Host Management Services |
| InfoServ | InfoServ | InfoServ | services.atl.chat | Information Service |
| HelpServ | HelpServ | HelpServ | services.atl.chat | Help Services |
| StatServ | StatServ | StatServ | services.atl.chat | Statistics Services |
| Global | Global | Global | services.atl.chat | Network Announcements |
| ALIS | ALIS | alis | services.atl.chat | Channel Directory |
| Proxyscan | Proxyscan | dnsbl | services.atl.chat | Proxyscan Service |
| GameServ | GameServ | GameServ | services.atl.chat | Game Services |
| RPGServ | RPGServ | RPGServ | services.atl.chat | RPG Finding Services |
Example: ATHEME_NICKSERV_NICK=NickServ, ATHEME_NICKSERV_USER=NickServ, ATHEME_NICKSERV_HOST=services.atl.chat, ATHEME_NICKSERV_REAL="Nickname Services".
WebPanel (UnrealIRCd admin UI)
| Variable | Description | Default (.env.example) |
|---|
WEBPANEL_PORT | Host port mapping (infra/compose/irc.yaml) | Often 8080 (optional in .env.example; uncomment to set) |
WEBPANEL_RPC_USER | UnrealIRCd JSON-RPC user | adminpanel |
WEBPANEL_RPC_PASSWORD | UnrealIRCd JSON-RPC password | change_me_webpanel_password |
Warning: RPC credentials are full admin access to UnrealIRCd’s API.
The Lounge
| Variable | Description | Required | Default |
|---|
THELOUNGE_PORT | Port for The Lounge web IRC client | Yes | 9000 |
THELOUNGE_WEBIRC_PASSWORD | WebIRC password for The Lounge to authenticate with UnrealIRCd | Yes | change_me_thelounge_webirc |
THELOUNGE_DELETE_UPLOADS_AFTER_MINUTES | Auto-delete uploaded files after this many minutes | No | 1440 |
Warning: THELOUNGE_WEBIRC_PASSWORD must match the WebIRC password configured in UnrealIRCd. Change this from the default before production deployment.
ObsidianIRC (optional compose fragment)
Commented examples in .env.example; enable when using infra/compose/obsidianirc.yaml. Values are build args — change .env then just obsidianirc rebuild.
| Variable | Description | Example |
|---|
OBSIDIANIRC_PORT | Published port | 8090 |
OBSIDIANIRC_IRC_WS_URL | Browser → IRC WebSocket | wss://irc.localhost/ws |
OBSIDIANIRC_SERVER_NAME | Server label in client UI | irc.localhost |
OBSIDIANIRC_AUTOJOIN | Channels to auto-join | #general |
XMPP Service (Prosody)
Prosody reads optional tuneables from the environment in apps/prosody/config/prosody.cfg.lua. Only a subset appears in .env.example. For tables below, the Default column is the fallback when the variable is unset, as implemented in prosody.cfg.lua (not necessarily what .env.example sets).
Domain and admin
| Variable | Description | Default (.env.example) |
|---|
XMPP_DOMAIN | Primary VirtualHost / cert identity | xmpp.localhost |
PROSODY_DOMAIN | Often set equal to XMPP_DOMAIN for templates | xmpp.localhost |
PROSODY_ADMIN_JID | Admin JID (mod_admin_adhoc, etc.) | admin@xmpp.localhost |
PROSODY_ADMIN_EMAIL | Contact string in config | admin@allthingslinux.org |
Storage
| Variable | Description |
|---|
| (omit) | Default in prosody.cfg.lua: SQLite file storage (typical dev). |
PROSODY_STORAGE=sql | Use SQL backend; then set PostgreSQL vars below (see commented block in .env.example). |
Database (only when PROSODY_STORAGE=sql)
| Variable | Description | Example |
|---|
PROSODY_DB_DRIVER | SQL driver name | PostgreSQL |
PROSODY_DB_HOST | DB hostname (compose service) | xmpp-postgres |
PROSODY_DB_PORT | DB port | 5432 |
PROSODY_DB_NAME | Database name | prosody |
PROSODY_DB_USER | DB user | prosody |
PROSODY_DB_PASSWORD | DB password | (strong secret) |
Warning: Restrict DB network access to Prosody only in production.
Ports
| Variable | Description | Required | Default |
|---|
PROSODY_C2S_PORT | Client-to-server port | Yes | 5222 |
PROSODY_S2S_PORT | Server-to-server port | Yes | 5269 |
PROSODY_HTTP_PORT | HTTP port (BOSH/WebSocket) | Yes | 5280 |
PROSODY_HTTPS_PORT | HTTPS port (via nginx) | Yes | 5281 |
PROSODY_C2S_DIRECT_TLS_PORT | Direct TLS client port | No | 5223 |
PROSODY_S2S_DIRECT_TLS_PORT | Direct TLS server port | No | 5270 |
PROSODY_PROXY65_PORT | SOCKS5 bytestream proxy port | No | 5000 |
TURN/STUN
| Variable | Description | Required | Default |
|---|
TURN_PORT | TURN server port | No | 3478 |
TURNS_PORT | TURN over TLS port | No | 5349 |
TURN_SECRET | Shared secret for TURN authentication | Yes | change_me_turn_secret |
TURN_EXTERNAL_HOST | External hostname for TURN server | Yes | turn.atl.network |
Warning: TURN_SECRET is a shared authentication secret. Generate a strong random value for production.
Security
| Variable | Description | Required | Default |
|---|
PROSODY_OAUTH2_REGISTRATION_KEY | OAuth2 registration key | Yes | change_me_prosody_oauth2_registration_key (.env.example) |
PROSODY_ALLOW_PLACEHOLDER_KEY | Allow placeholder OAuth2 key (dev only) | No | true in example — set false in prod |
PROSODY_ALLOW_REGISTRATION | Allow public registration | No | false (cfg default when unset) |
PROSODY_C2S_REQUIRE_ENCRYPTION | Require TLS for c2s | No | true (relaxed in .env.dev) |
PROSODY_S2S_REQUIRE_ENCRYPTION | Require TLS for s2s | No | true |
PROSODY_S2S_SECURE_AUTH | Verified certs for s2s | No | true |
PROSODY_ALLOW_UNENCRYPTED_PLAIN_AUTH | Plain auth without TLS | No | false |
PROSODY_MAX_CONNECTIONS_PER_IP | Max connections per IP | No | 5 |
PROSODY_REGISTRATION_THROTTLE_MAX | Registrations per throttle window | No | 3 |
PROSODY_REGISTRATION_THROTTLE_PERIOD | Throttle window (seconds) | No | 3600 |
PROSODY_BLOCK_REGISTRATIONS_REQUIRE | Username regex | No | ^[a-zA-Z0-9_.-]+$ |
PROSODY_TLS_CHANNEL_BINDING | TLS channel binding | No | true (unset enables binding; set to false to disable) |
Warning: Rotate PROSODY_OAUTH2_REGISTRATION_KEY for production; do not ship PROSODY_ALLOW_PLACEHOLDER_KEY=true publicly.
HTTP, upload URLs, and admin API
| Variable | Description | Default (.env.example) |
|---|
PROSODY_HTTP_HOST | HTTP bind / advertised host | localhost (cfg) |
PROSODY_HTTP_SCHEME | http or https | http (cfg) |
PROSODY_HTTP_EXTERNAL_URL | BOSH/WebSocket base for clients | http://xmpp.localhost:5280/ |
PROSODY_HTTPS_VIA_PROXY | Terminate HTTPS at nginx/proxy | false |
PROSODY_UPLOAD_EXTERNAL_URL | Public upload URL | https://xmpp.localhost:5281/upload/ |
PROSODY_PROXY_ADDRESS | Proxy hostname in generated URLs | xmpp.localhost |
PROSODY_REST_URL | Base URL for mod_http_admin_api | http://atl-xmpp-server:5280/admin_api |
PROSODY_REST_TOKEN | Bearer for admin API (Portal provisioning); just prosody-token | (empty) |
Legacy Basic-auth vars (PROSODY_REST_USERNAME, PROSODY_REST_PASSWORD) are not in current .env.example; prefer Bearer token.
TLS certificates (paths inside Prosody container)
| Variable | Description | Default (.env.example) |
|---|
PROSODY_SSL_KEY | Private key path | /etc/prosody/certs/live/xmpp.localhost/privkey.pem |
PROSODY_SSL_CERT | Full chain path | /etc/prosody/certs/live/xmpp.localhost/fullchain.pem |
Warning: Never commit private keys.
Logging and statistics
| Variable | Description | Required | Default |
|---|
PROSODY_LOG_LEVEL | Log verbosity (debug, info, warn, error) | No | info |
PROSODY_STATISTICS | Statistics backend (internal or statsd) | No | internal |
PROSODY_STATISTICS_INTERVAL | Statistics collection interval | No | manual |
PROSODY_OPENMETRICS_IP | IP address for OpenMetrics endpoint | No | 127.0.0.1 |
PROSODY_OPENMETRICS_CIDR | CIDR range allowed to access OpenMetrics | No | 172.16.0.0/12 |
Message Archiving (MAM)
| Variable | Description | Required | Default |
|---|
PROSODY_ARCHIVE_EXPIRES_AFTER | Archive retention period | No | 1y |
PROSODY_ARCHIVE_POLICY | Enable message archiving | No | true |
PROSODY_ARCHIVE_COMPRESSION | Enable archive compression | No | true |
PROSODY_ARCHIVE_STORE | Archive storage backend name | No | archive |
PROSODY_ARCHIVE_MAX_QUERY_RESULTS | Maximum results per MAM query | No | 250 |
PROSODY_MAM_SMART_ENABLE | Enable smart MAM (archive only when needed) | No | false (set env to true to enable) |
MUC (Multi-User Chat)
| Variable | Description | Required | Default |
|---|
PROSODY_MUC_NOTIFICATIONS | Enable MUC notifications | No | true |
PROSODY_MUC_OFFLINE_DELIVERY | Deliver messages to offline MUC participants | No | true |
PROSODY_BRIDGE_MUC_JID | Bridge JID for MUC-related ACL defaults in config | No | bridge. + primary domain (e.g. bridge.xmpp.localhost) |
XMPP_WEBCHAT_URL | MUC disco#info webchat URL; {jid} → room JID. Set when using Fluux / compose that passes it | No | (optional; see .env.example comment) |
PROSODY_RESTRICT_ROOM_CREATION | Restrict who can create rooms | No | false |
PROSODY_MUC_DEFAULT_PUBLIC | New rooms are public by default | No | true |
PROSODY_MUC_DEFAULT_PERSISTENT | New rooms are persistent by default | No | true |
PROSODY_MUC_DEFAULT_PUBLIC_JIDS | Show participant JIDs by default | No | true |
PROSODY_MUC_LOCKING | Lock rooms until configured | No | false |
PROSODY_MUC_LOG_BY_DEFAULT | Log MUC messages by default | No | true |
PROSODY_MUC_LOG_EXPIRES_AFTER | MUC log retention period | No | 1y |
PROSODY_MUC_LOG_PRESENCES | Log presence changes in MUC | No | false |
PROSODY_MUC_LOG_ALL_ROOMS | Log all rooms regardless of room setting | No | false |
PROSODY_MUC_LOG_CLEANUP_INTERVAL | Cleanup interval for expired logs (seconds) | No | 86400 |
PROSODY_MUC_MAX_ARCHIVE_QUERY_RESULTS | Maximum MUC archive query results | No | 100 |
PROSODY_MUC_LOG_STORE | MUC log storage backend name | No | muc_log |
PROSODY_MUC_LOG_COMPRESSION | Enable MUC log compression | No | true |
PROSODY_MUC_MAM_SMART_ENABLE | Enable smart MAM for MUC | No | false |
Rate limiting
| Variable | Description | Required | Default |
|---|
PROSODY_C2S_RATE | Client-to-server rate limit | No | 10kb/s |
PROSODY_C2S_BURST | Client-to-server burst allowance | No | 25kb |
PROSODY_C2S_STANZA_SIZE | Maximum c2s stanza size (bytes) | No | 262144 |
PROSODY_S2S_RATE | Server-to-server rate limit | No | 30kb/s |
PROSODY_S2S_BURST | Server-to-server burst allowance | No | 100kb |
PROSODY_S2S_STANZA_SIZE | Maximum s2s stanza size (bytes) | No | 524288 |
PROSODY_HTTP_UPLOAD_RATE | HTTP upload rate limit | No | 2mb/s |
PROSODY_HTTP_UPLOAD_BURST | HTTP upload burst allowance | No | 10mb |
Push notifications
| Variable | Description | Required | Default |
|---|
PROSODY_PUSH_IMPORTANT_BODY | Body text for important push notifications | No | New Message! |
PROSODY_PUSH_MAX_ERRORS | Maximum push errors before disabling | No | 16 |
PROSODY_PUSH_MAX_DEVICES | Maximum push devices per user | No | 5 |
PROSODY_PUSH_MAX_HIBERNATION_TIMEOUT | Maximum hibernation timeout (seconds) | No | 259200 |
PROSODY_PUSH_NOTIFICATION_WITH_BODY | Include message body in push | No | false |
PROSODY_PUSH_NOTIFICATION_WITH_SENDER | Include sender in push | No | false |
Account lifecycle
| Variable | Description | Required | Default |
|---|
PROSODY_ACCOUNT_INACTIVE_PERIOD | Seconds before an account is considered inactive | No | 31536000 |
PROSODY_ACCOUNT_GRACE_PERIOD | Grace period before inactive account cleanup (seconds) | No | 2592000 |
Server info
| Variable | Description | Required | Default |
|---|
PROSODY_SERVER_NAME | Server display name | No | localhost |
PROSODY_SERVER_WEBSITE | Server website URL | No | http://localhost |
PROSODY_SERVER_DESCRIPTION | Server description | No | XMPP Service |
PROSODY_SUPPORT_CONTACT | Support JID advertised in service discovery | No | support@ + primary XMPP domain (same rule as PROSODY_DOMAIN / XMPP_DOMAIN) |
PROSODY_SUPPORT_CONTACT_NICK | Support contact display nick | No | Support |
Used only by prosody.cfg.lua (not listed in .env.example).
| Variable | Description | Required | Default (if unset) |
|---|
LUA_GC_STEP_SIZE | Lua garbage collector step size | No | 13 |
LUA_GC_PAUSE | Lua GC pause parameter | No | 110 |
LUA_GC_SPEED | Lua GC speed parameter | No | 200 |
LUA_GC_THRESHOLD | Lua GC threshold parameter | No | 120 |
PubSub feeds
| Variable | Description | Required | Default |
|---|
PROSODY_FEED_URL | Atom/RSS feed URL for PubSub | No | https://allthingslinux.org/feed |
Bridge Service (Discord↔IRC↔XMPP relay)
Warning: BRIDGE_DISCORD_TOKEN is a full Discord bot credential — never commit. BRIDGE_PORTAL_TOKEN must equal the Portal’s BRIDGE_SERVICE_TOKEN when identity lookup is enabled.
Discord and Portal
| Variable | Description | Default (.env.example) |
|---|
BRIDGE_DISCORD_TOKEN | Discord bot token | (empty; set to run bridge) |
BRIDGE_DISCORD_CHANNEL_ID | Channel to bridge | (empty) |
BRIDGE_PORTAL_BASE_URL | Portal origin (e.g. https://portal.example.com) | (empty) — set in prod with Portal |
BRIDGE_PORTAL_TOKEN | Shared secret for /api/bridge/identity | (empty) |
XMPP component
| Variable | Description | Default (.env.example) |
|---|
BRIDGE_XMPP_COMPONENT_JID | Component JID | bridge.xmpp.localhost |
BRIDGE_XMPP_COMPONENT_SECRET | Component secret (match Prosody) | change_me_xmpp_component_secret |
BRIDGE_XMPP_COMPONENT_SERVER | Prosody hostname in Docker network | atl-xmpp-server |
BRIDGE_XMPP_COMPONENT_PORT | Component listener port | 5347 |
IRC
| Variable | Description | Default (.env.example) |
|---|
BRIDGE_IRC_NICK | Bridge bot nick | bridge |
BRIDGE_IRC_OPER_PASSWORD | Oper password for bridge (if used) | (empty in example) |
IRC_BRIDGE_SERVER | IRC server hostname in Docker network | atl-irc-server |
BRIDGE_IRC_TLS_VERIFY | Verify IRC TLS from bridge | false (enable true with real certs) |
| Variable | Description | Default (.env.example) |
|---|
BRIDGE_RELAYMSG_CLEAN_NICKS | Cleaner RELAYMSG nicks (UnrealIRCd require-separator no) | true |
BRIDGE_IRC_REDACT_ENABLED | Enable IRC-side redaction handling | false |
XMPP_AVATAR_BASE_URL | Internal HTTP base for avatar checks | http://atl-xmpp-server:5280 |
XMPP_AVATAR_PUBLIC_URL | Optional public base for avatar URLs | (empty) |
XMPP_UPLOAD_FETCH_URL | Internal base for upload fetch / Discord media | http://atl-xmpp-server:5280 |
Dev-only (no Portal)
Commented in .env.dev.example: BRIDGE_DEV_IRC_PUPPETS, BRIDGE_DEV_IRC_NICK_MAP — per-user IRC connections for local testing.
| Variable | Description | Default |
|---|
IRC_PUPPET_IDLE_TIMEOUT_HOURS | Disconnect idle IRC puppet connections after this many hours | 24 |
Env overrides vs config.yaml
These environment variables override the corresponding fields in the bridge’s YAML config when set (see apps/bridge/src/bridge/config/schema.py): BRIDGE_IRC_REDACT_ENABLED, BRIDGE_RELAYMSG_CLEAN_NICKS, BRIDGE_IRC_TLS_VERIFY.
Logging
| Variable | Description | Default |
|---|
LOG_LEVEL | DEBUG, INFO, WARNING, ERROR | INFO (.env.example); DEBUG in .env.dev.example |
Web frontend (apps/web, Next.js)
| Variable | Description | Default (.env.example) |
|---|
NEXT_PUBLIC_IRC_WS_URL | Browser → IRC WebSocket | wss://irc.localhost/ws |
NEXT_PUBLIC_XMPP_BOSH_URL | Browser → XMPP BOSH (/http-bind on Prosody HTTP) | https://xmpp.localhost:5281/http-bind (TLS via atl-xmpp-nginx; use http://localhost:5280/http-bind for plain HTTP to Prosody, e.g. just web dev) |
XMPP WebSocket (RFC 7395) is served at path /xmpp-websocket on Prosody’s HTTP stack. With the dockerized nginx sidecar, use wss://<XMPP_DOMAIN>:5281/xmpp-websocket (or wss://…/ws, which nginx proxies to the same upstream). Do not confuse with BOSH at /http-bind.
NEXT_PUBLIC_* values are baked in at build time for the web app — set them before pnpm build / image build for your domain.
Fluux messenger (infra/compose/fluux-messenger.yaml)
| Variable | Description | Default (.env.example) |
|---|
FLUUX_VERSION | Fluux image / ref tag | v0.13.3 |
FLUUX_DOMAIN | Public vhost for the messenger | webxmpp.atl.chat |
FLUUX_CERT_DOMAIN | Cert / TLS identity helper | atl.chat |
FLUUX_MESSENGER_PORT | HTTP port | 8091 |
FLUUX_MESSENGER_HTTPS_PORT | HTTPS port | 8443 |
XMPP_DOMAIN | Prosody host header for Fluux’s /ws → Prosody proxy | Same as XMPP_DOMAIN / JID domain (e.g. xmpp.localhost) |
Fluux’s default URLs use port 443 (https://<jid-domain>/.well-known/…, wss://<jid-domain>/ws). atl-xmpp-nginx publishes 127.0.0.1:443 → :443 (same TLS as 5281) so those defaults work. If you cannot bind 127.0.0.1:443, drop that mapping and set Server (optional) to wss://<XMPP_DOMAIN>:5281/ws or wss://localhost:8443/ws (Fluux-side proxy after rebuild).
Docs (Cloudflare Workers via Alchemy)
| Variable | Description | Required | Default |
|---|
ALCHEMY_PASSWORD | Password used by Alchemy to encrypt deployment state secrets | Yes | change-me |
Warning: ALCHEMY_PASSWORD encrypts secrets in the deployment state. Use a strong, unique value and do not share it. Required only when running pnpm run deploy or pnpm run destroy from apps/docs.
Optional compose-only variables
Listed as comments in .env.example when they apply only if you enable a fragment or override:
| Variable | Purpose |
|---|
IRC_SERVICES_SERVER | Override UnrealIRCd → Atheme link hostname |
IRC_ENABLE_GEOIP_CLASSIC | GeoIP classic DB download at UnrealIRCd startup |
WEBPANEL_PORT | Host port for WebPanel (infra/compose/irc.yaml) |
XMPP_WEBCHAT_URL | Passed into Prosody for MUC webchat discovery |
SSL_DOMAIN | Cert-manager helper (infra/compose/cert-manager.yaml) |
OBSIDIANIRC_* | ObsidianIRC build args (see ObsidianIRC) |
Portal integration (external ATL Portal)
The Portal app reads these from its own apps/portal/.env (see Portal docs/ENV_VARS.md). They are not substituted by prepare-config.sh in atl.chat; document them here so operators can align URLs and secrets with this stack.
Typical values when Portal talks to Docker service hostnames (from Portal’s container network) vs public hostnames (from a host-run Portal) differ — use the hostname Portal can actually reach.
| Variable | Role |
|---|
IRC_ATHEME_JSONRPC_URL | Atheme JSON-RPC, e.g. http://atl-irc-server:8081/jsonrpc |
IRC_UNREAL_JSONRPC_URL | UnrealIRCd JSON-RPC HTTPS URL |
IRC_UNREAL_RPC_USER / IRC_UNREAL_RPC_PASSWORD | Match WEBPANEL_RPC_* |
PROSODY_REST_URL | Prosody admin API base — include path, e.g. http://atl-xmpp-server:5280/admin_api |
PROSODY_REST_TOKEN | Bearer from just prosody-token (preferred) |
PROSODY_REST_USERNAME / PROSODY_REST_PASSWORD | Legacy HTTP Basic for admin API — avoid if Bearer is configured |
IRC_SERVER / IRC_PORT | Client-style IRC connection target |
Warning: Treat RPC and REST tokens as admin credentials; rotate defaults before production.
.env.dev overlay (just dev)
Compose loads .env then .env.dev. The committed .env.example is already localhost-oriented; .env.dev.example reiterates dev-safe TLS and adds bridge/docs-friendly defaults.
| Variable | Typical purpose |
|---|
ATL_CHAT_IP, ATL_GATEWAY_IP | 127.0.0.1 — local bind |
IRC_DOMAIN, XMPP_DOMAIN, PROSODY_DOMAIN | *.localhost hostnames |
IRC_SSL_CERT_PATH, IRC_SSL_KEY_PATH | Paths for dev certs |
IRC_TLS_VERIFY, IRC_LOUNGE_REJECT_UNAUTHORIZED, IRC_WEBSOCKET_USE_TLS, BRIDGE_IRC_TLS_VERIFY | Dev TLS behaviour |
PROSODY_ALLOW_PLACEHOLDER_KEY, PROSODY_HTTPS_VIA_PROXY | Local Prosody convenience |
PROSODY_UPLOAD_EXTERNAL_URL, PROSODY_HTTP_EXTERNAL_URL, PROSODY_PROXY_ADDRESS, PROSODY_SSL_KEY, PROSODY_SSL_CERT | URLs and cert paths for dev |
PROSODY_C2S_REQUIRE_ENCRYPTION, PROSODY_S2S_REQUIRE_ENCRYPTION, PROSODY_S2S_SECURE_AUTH, PROSODY_ALLOW_UNENCRYPTED_PLAIN_AUTH | Relaxed crypto for self-signed / plain |
BRIDGE_XMPP_COMPONENT_JID, BRIDGE_PORTAL_BASE_URL, BRIDGE_RELAYMSG_CLEAN_NICKS, LOG_LEVEL | Bridge: local JID, empty Portal URL, verbose logs |
XMPP_AVATAR_BASE_URL, XMPP_UPLOAD_FETCH_URL | Docker-internal Prosody HTTP for bridge |
NEXT_PUBLIC_IRC_WS_URL, NEXT_PUBLIC_XMPP_BOSH_URL | Local web app endpoints |
Uncomment and fill when needed:
| Variable | Purpose |
|---|
BRIDGE_PORTAL_BASE_URL, BRIDGE_PORTAL_TOKEN | Portal on host (e.g. http://host.docker.internal:3000) — token must match Portal BRIDGE_SERVICE_TOKEN |
PROSODY_REST_URL, PROSODY_REST_TOKEN | Portal-driven XMPP provisioning (just prosody-token) |
BRIDGE_DEV_IRC_PUPPETS, BRIDGE_DEV_IRC_NICK_MAP | Dev IRC puppets without Portal |
Related pages
- Ports Reference — complete port registry with all service ports
- API Reference — Portal API and UnrealIRCd JSON-RPC endpoints
- Glossary — definitions of project-specific terms and acronyms
- FAQ — frequently asked questions about atl.chat
- Security — secret generation and credential rotation for sensitive variables
- Deployment — production deployment using these variables