Prosody
Table of Contents
2. Start here
3. Configuration
3.1. Main configuration patch
SQLite3 database requires package lua-dbi-sqlite3 on Debian.
diff -u --label \#\<buffer\ prosody.cfg.lua.orig\> --label \#\<buffer\ prosody.cfg.lua\> /tmp/buffer-content-j2LvYF /tmp/buffer-content-wP6gy2 --- #<buffer prosody.cfg.lua.orig> +++ #<buffer prosody.cfg.lua> @@ -23,7 +23,7 @@ -- for the server. Note that you must create the accounts separately -- (see https://prosody.im/doc/creating_accounts for info) -- Example: admins = { "user1@example.com", "user2@example.net" } -admins = { } +admins = { "alan@example.org" } -- This option allows you to specify additional locations where Prosody -- will search first for modules. For additional modules you can install, see @@ -65,12 +65,12 @@ "register"; -- Allow users to register on this server using a client and change passwords "time"; -- Let others know the time here on this server "uptime"; -- Report how long server has been running - "version"; -- Replies to server version requests - --"mam"; -- Store recent messages to allow multi-device synchronization + --"version"; -- Replies to server version requests + "mam"; -- Store recent messages to allow multi-device synchronization --"turn_external"; -- Provide external STUN/TURN service for e.g. audio/video calls -- Admin interfaces - "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands + --"admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands "admin_shell"; -- Allow secure administration via 'prosodyctl shell' -- HTTP modules @@ -79,17 +79,17 @@ --"websocket"; -- XMPP over WebSockets -- Other specific functionality - "posix"; -- POSIX functionality, sends server to background, enables syslog, etc. + --"posix"; -- POSIX functionality, sends server to background, enables syslog, etc. --"announce"; -- Send announcement to all online users --"groups"; -- Shared roster support - --"mimicking"; -- Prevent address spoofing + "mimicking"; -- Prevent address spoofing --"motd"; -- Send a message to users when they log in --"proxy65"; -- Enables a file transfer proxy service which clients behind NAT can use --"s2s_bidi"; -- Bi-directional server-to-server (XEP-0288) --"server_contact_info"; -- Publish contact information for this service - --"tombstones"; -- Prevent registration of deleted accounts - --"watchregistrations"; -- Alert admins of registrations - --"welcome"; -- Welcome users who register accounts + "tombstones"; -- Prevent registration of deleted accounts + "watchregistrations"; -- Alert admins of registrations + "welcome"; -- Welcome users who register accounts } -- These modules are auto-loaded, but should you want @@ -97,7 +97,7 @@ modules_disabled = { -- "offline"; -- Store offline messages -- "c2s"; -- Handle client connections - -- "s2s"; -- Handle server-to-server connections + "s2s"; -- Handle server-to-server connections } -- Debian: @@ -156,11 +156,11 @@ -- through modules. An "sql" backend is included by default, but requires -- additional dependencies. See https://prosody.im/doc/storage for more info. ---storage = "sql" -- Default is "internal" (Debian: "sql" requires one of the +storage = "sql" -- Default is "internal" (Debian: "sql" requires one of the -- lua-dbi-sqlite3, lua-dbi-mysql or lua-dbi-postgresql packages to work) -- For the "sql" backend, you can uncomment *one* of the below to configure: ---sql = { driver = "SQLite3", database = "prosody.sqlite" } -- Default. 'database' is the filename. +sql = { driver = "SQLite3", database = "prosody.sqlite" } -- Default. 'database' is the filename. --sql = { driver = "MySQL", database = "prosody", username = "prosody", password = "secret", host = "localhost" } --sql = { driver = "PostgreSQL", database = "prosody", username = "prosody", password = "secret", host = "localhost" } @@ -171,7 +171,7 @@ -- they are offline. This setting controls how long Prosody will keep -- messages in the archive before removing them. -archive_expires_after = "1w" -- Remove archived messages after 1 week +archive_expires_after = "6 months" -- Remove archived messages after 6 months -- You can also configure messages to be stored in-memory only. For more -- archiving options, see https://prosody.im/doc/modules/mod_mam @@ -233,7 +233,7 @@ -- Component definitions in their own config files. This line includes -- all config files in /etc/prosody/conf.d/ -VirtualHost "localhost" +--VirtualHost "localhost" -- Prosody requires at least one enabled VirtualHost to function. You can -- safely remove or disable 'localhost' once you have added another. Diff finished. Mon Jun 8 05:37:22 2026
3.2. VirtualHost configuration
- https://prosody.im/doc/modules/mod_http_file_share
- https://prosody.im/doc/http#reverse_proxy
- notes:nginx#reverse-proxy-example <– for http_file_share
-- /etc/prosody/conf.avail/example.org.cfg.lua VirtualHost "example.org" Component "share.example.org" "http_file_share" modules_disabled = { "s2s" } http_file_share_size_limit = 1*1024*1024*1024 -- 1 GiB http_file_share_daily_quota = 2*1024*1024*1024 -- 2 GiB http_external_url = "https://share.example.org/" http_paths = { file_share = "/"; -- Serve from base URL }
See Reverse proxy for the nginx setup
4. Let’s Encrypt
Add VirtualHost beforehand: https://prosody.im/doc/configure#adding_a_host
Do not change the global certificates location to /etc/letsencrypt/live it
will lead to permissions issues, the following setup will import them from
/etc/letsencrypt/live to /etc/prosody/certs
4.1. Automate with certbot
Create a deploy hook script in /etc/letsencrypt/renewal-hooks/deploy/prosody.sh
#!/bin/sh /usr/bin/prosodyctl --root cert import /etc/letsencrypt/live
Make the script executable
chmod 700 /etc/letsencrypt/renewal-hooks/deploy/prosody.sh
Force renew to check if the deploy hook script works
certbot renew --force-renewal
Make sure the deploy hook script imported the certificates in /etc/prosody/certs
ls /etc/prosody/certs
Finally check with prosodyctl for any errors
prosodyctl check certs
5. Ports and network configuration
TCP Port 5222 for c2s (client to server) connections and standard
HTTP ports for file sharing through nginx reverse proxy.
6. DNS records
7. Creating accounts / Changing password / Allowing registrations
- https://prosody.im/doc/creating_accounts
- https://prosody.im/doc/public_servers <– best practices (backups, abuse prevention etc)
prosodyctl adduser alan@example.org
- Registration of new accounts is disabled by default
7.1. Change user password
prosodyctl passwd JID
8. Roles (e.g operator, admin, member etc)
- https://prosody.im/doc/roles
- https://prosody.im/doc/roles#manual-role-assignment <– e.g. to add new admin
9. Built-in interactive shell
10. Useful commands
prosodyctl help prosodyctl status prosodyctl check
11. References
- https://prosody.im/doc
- https://prosody.im/doc/modules/
- https://blog.trueelena.org/blog/2025/07/15-federated-instant-messaging-100-debianized/index.html
- https://docs.trueelena.org/self_hosting/modern_xmpp_server/index.html
- https://manpages.debian.org/stable/prosody/prosodyctl.1
- https://voxelmanip.se/2025/06/25/setting-up-an-xmpp-server-with-prosody/