Prosody

Table of Contents

1. Description

Prosody is a modern XMPP communication server.

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

-- /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

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)

9. Built-in interactive shell

10. Useful commands

prosodyctl help
prosodyctl status
prosodyctl check

11. References

lun. 13 juillet 2026

Generated with Emacs 30.1 (Org mode 9.7.11)