Files
prosody/README.md

162 lines
5.3 KiB
Markdown
Raw Normal View History

2026-02-02 20:12:50 +03:00
# Prosody XMPP Server
2026-02-02 20:11:48 +03:00
2026-02-02 20:12:50 +03:00
Dockerized Prosody XMPP server with MySQL backend.
## Prerequisites
- Docker and Docker Compose
- External MySQL network: `mysqlgit_mysql_network`
- Environment variables configuration (see Configuration section)
## Configuration
This setup uses environment variables for configuration. Create a `.env` file in the project root with:
```env
# XMPP Configuration
XMPP_DOMAIN=xmpp.guschin.info
XMPP_USER=mish
XMPP_PASSWORD=your_password
# MySQL Configuration
MYSQL_HOST=mysql
MYSQL_USER=prosody
MYSQL_PASSWORD=your_mysql_password
MYSQL_DATABASE=prosody
```
## Starting the Server
Run from the project directory:
```bash
docker-compose up -d
```
This will:
- Build and start the Prosody container
- Connect to external MySQL network (`mysqlgit_mysql_network`)
- Wait for MySQL to be ready
- Generate self-signed SSL/TLS certificates (if not present)
- Configure Prosody with MySQL backend
## Access Points
| Service | Port | Description |
|---------|------|-------------|
| C2S (Client to Server) | 5222 | XMPP client connections |
| S2S (Server to Server) | 5269 | XMPP federation |
| Component Protocol | 5347 | External components |
| HTTP/BOSH/WebSocket | 5280 | Web-based connections |
| HTTPS | 5281 | Secure web connections |
| STUN/TURN | 3478 (UDP+TCP) | NAT traversal for audio/video calls |
| STUN/TURN over TLS | 5349 (UDP+TCP) | Encrypted TURN (`turns:`) |
| TURN relay range | 49160-49200 (UDP) | Media relay ports |
2026-02-02 20:12:50 +03:00
## Features
- **Virtual Host**: `xmpp.guschin.info`
- **Multi-User Chat (MUC)**: `muc.xmpp.guschin.info`
- **Storage**: MySQL backend with SQL storage
- **Admin User**: `admin@guschin.info`
- **Health Checks**: Automatic container health monitoring
- **Memory Limit**: 200M
- **Auto-restart**: Container restarts unless stopped
## Enabled Modules
Core modules: roster, saslauth, tls, dialback, disco, carbons, pep, private, blocking, vcard, version, uptime, time, ping, register, last_activity, admin_adhoc, muc_mam
## Data Persistence
Volumes are mounted to persist data:
- `./data/prosody``/var/lib/prosody`
- `./logs/prosody``/var/log/prosody`
- `./data/prosody/configuration``/etc/prosody/conf.d`
## Connecting Clients
Use any XMPP client with:
- **Server**: xmpp.guschin.info
- **Port**: 5222
- **Username**: your configured user
- **Domain**: xmpp.guschin.info
## Audio/Video Calls (Jingle)
Voice and video calls use Jingle (XEP-0166/0167/0176). Prosody only carries the
signalling; media flows directly between clients, falling back to a TURN relay
when NAT prevents a direct path.
Two pieces make this work:
- **coturn** (`coturn` container) — the STUN/TURN server. Runs with host
networking because a relay needs its whole UDP port range reachable.
- **`mod_turn_external`** in Prosody — advertises coturn to clients over
XEP-0215 and issues time-limited TURN credentials.
### Configuration
`TURN_SECRET` in `.env` must match `static-auth-secret` in
[coturn/turnserver.conf](coturn/turnserver.conf). `.env` is gitignored, so
these values are set per-deployment and not committed:
```env
TURN_HOST=guschin.info
TURN_SECRET=<same value as static-auth-secret>
```
`TURN_HOST` is `guschin.info`, not `turn.guschin.info`: `turns:` (TLS) clients
validate the hostname against the certificate, and only `guschin.info` is in
the current cert's SANs. To use `turn.guschin.info` instead, reissue the
certificate with that name added and update both `TURN_HOST` and the
`external-ip`/`cert` settings accordingly.
`turnserver.conf` pins the server's public address in three places:
`listening-ip`, `relay-ip`, and `external-ip`. **Update all three if the
server IP changes**, otherwise coturn advertises relay candidates that peers
cannot reach. Pinning them also stops coturn from auto-discovering the Docker
bridge interfaces and relaying on unreachable private addresses.
### Verifying
Check that Prosody advertises the service and coturn answers:
```bash
docker logs coturn # should show listeners on 3478/5349
docker exec prosody-xmpp prosodyctl check config
```
From a client, place a call between two accounts. Clients that support Jingle
audio/video include Conversations (Android), Dino, Gajim, and Monal (iOS).
Note that Jingle A/V is client-to-client — both parties need a client that
supports it.
### Certificate renewal
`coturn/entrypoint.sh` copies the certificate at container start, because
coturn runs as `nobody` and cannot read Let's Encrypt's root-only
`privkey.pem` directly. A renewal therefore needs a container restart, which
the certbot deploy hook on the server handles (outside this repo):
```
/etc/letsencrypt/renewal-hooks/deploy/restart-prosody.sh
```
It restarts both `prosody-xmpp` and `coturn` when the `guschin.info` or
`xmpp.guschin.info` lineage is renewed. Without the coturn restart, `turns:`
on 5349 would keep serving the old certificate until the next restart.
### Firewall
Ports 3478 and 5349 (both UDP and TCP) plus the UDP relay range 49160-49200
must be reachable from the internet. The host has no local firewall
(`iptables` INPUT policy is ACCEPT), but any provider-level firewall needs
these opened.
2026-02-02 20:12:50 +03:00
## Notes
- TLS encryption is not required by default (configurable in [prosody.cfg.lua](data/prosody/configuration/prosody.cfg.lua))
- Self-signed certificates are auto-generated on first run
- The container depends on an external MySQL network named `mysqlgit_mysql_network`