Cloudron makes it easy to run web apps like WordPress, Nextcloud, GitLab on your server. Find out more or install now.


Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Bookmarks
  • Search
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo

Cloudron Forum

Apps | Demo | Docs | Install
  1. Cloudron Forum
  2. App Packaging & Development
  3. XMPP Server - Prosody

XMPP Server - Prosody

Scheduled Pinned Locked Moved App Packaging & Development
63 Posts 6 Posters 6.2k Views 7 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D djxx

    @girish Any update on this? I'd like to be able to keep tinkering on this before I forget all the prosody and cloudron stuff I crammed in my head 🙂

    L Offline
    L Offline
    LoudLemur
    wrote on last edited by
    #27

    @djxx said in XMPP Server - Prosody:

    @girish Any update on this? I'd like to be able to keep tinkering on this before I forget all the prosody and cloudron stuff I crammed in my head 🙂

    I know the feeling! We lose a lot if we suspend focus on a project for a while.

    1 Reply Last reply
    0
    • D djxx referenced this topic on
    • girishG Offline
      girishG Offline
      girish
      Staff
      wrote on last edited by
      #28

      @djxx Is https://github.com/DerekJarvis/cloudron-prosody still the latest code? We should have some free cycles coming up, so I thought we can take a look if this is something easily doable. I can't promise we will publish it since it seems quite complicated (it's why we had to remove Jitsi too, it became way too hard to fight their system). Was the cert issue the blocker for you to just use your custom image yourself?

      jdaviescoatesJ 1 Reply Last reply
      3
      • girishG girish

        @djxx Is https://github.com/DerekJarvis/cloudron-prosody still the latest code? We should have some free cycles coming up, so I thought we can take a look if this is something easily doable. I can't promise we will publish it since it seems quite complicated (it's why we had to remove Jitsi too, it became way too hard to fight their system). Was the cert issue the blocker for you to just use your custom image yourself?

        jdaviescoatesJ Offline
        jdaviescoatesJ Offline
        jdaviescoates
        wrote on last edited by jdaviescoates
        #29

        @girish it's possible that Snikket might be simpler to package:

        https://github.com/snikket-im/snikket-selfhosted

        I use Cloudron with Gandi & Hetzner

        1 Reply Last reply
        0
        • D Offline
          D Offline
          djxx
          wrote on last edited by djxx
          #30

          I was actually looking into Snikket again last night. Back when I did my first packaging of XMPP, Snikket was still a bit too limited in features. I'll take another look at Snikket, but I suspect it will have the same cert requirements as part of the XMPP protocol.

          And @girish , I don't remember perfectly, but based on my notes above the cert was the only thing I couldn't work around in the app package approach. While checking out Snikket I'll confirm if it also needs it.

          1 Reply Last reply
          1
          • D Offline
            D Offline
            djxx
            wrote on last edited by djxx
            #31

            Research done - it is indeed a limitation of Snikket's implementation of XMPP. from https://snikket.org/faq/:

            image.png

            1 Reply Last reply
            0
            • D Offline
              D Offline
              djxx
              wrote on last edited by
              #32

              The way both Snikket and Cloudron apps work, it would "technically" be a different domain to allow your XMPP usernames to be like: user@domain.com , instead of the uglier user@chat.domain.com . The SRV records are trivial, and the real limitation as far as Cloudron is concerned is the app getting the cert with the TLD.

              I guess there may be other apps in the future that would need the primary cert in order to verify trust between the TLD and the app itself - so perhaps this could be a new app option?

              Also, Snikket intends to be a "one and done" installation, and it packages its own TURN/STUN server. For that reason, I think it's not ideal to use as the XMPP solution since it will make the app heaver than it needs to be, and require more ports.

              1 Reply Last reply
              1
              • L Offline
                L Offline
                LoudLemur
                wrote on last edited by LoudLemur
                #33

                I had AI look at this, but it wasn't very fruitful. It suggests using Cloudron's wildcards and, for Prosody, using its ACME plugin which can obtain certificates:"Let's dive into the specific technical challenges and potential solutions for using Prosody on Cloudron:

                1. Domain Flexibility with Prosody:
                  Prosody is indeed more flexible than Snikket in this regard. You can configure Prosody to use different domains for XMPP addresses and the web portal. The key configuration options you'd need to focus on are:
                VirtualHost "example.com"
                  -- XMPP domain configuration
                
                http_host = "chat.example.com"
                  -- Web interface domain
                

                This separation isn't possible with Snikket's current setup.

                1. Certificate Handling:
                  The core issue here is obtaining a certificate for example.com when your Cloudron app is hosted at chat.example.com. Prosody itself doesn't solve this, but there are potential workarounds:

                a) Use Cloudron's wildcard certificate: If Cloudron provides a wildcard cert for *.example.com, you could use this for both the chat subdomain and the main domain.

                b) Manual certificate injection: You could manually obtain a certificate for example.com and inject it into the Prosody container. This would require modifying the Cloudron app to allow for custom certificate paths:

                ssl = {
                    certificate = "/path/to/custom/fullchain.pem";
                    key = "/path/to/custom/privkey.pem";
                }
                

                c) ACME plugin: Prosody has an ACME plugin that can obtain certificates. You'd need to ensure the Cloudron app has the necessary permissions to write these certificates and that the DNS challenge is used instead of HTTP:

                plugin_paths = { "/usr/lib/prosody/modules" }
                modules_enabled = {
                    "acme"
                }
                acme = {
                    provider = "letsencrypt",
                    challenge = "dns-01"
                }
                
                1. SRV Records:
                  Cloudron should allow you to set custom DNS records. You'd need to add:
                _xmpp-client._tcp.example.com. IN SRV 0 5 5222 chat.example.com.
                _xmpp-server._tcp.example.com. IN SRV 0 5 5269 chat.example.com.
                
                1. Cloudron Integration:
                  The existing GitHub repo is a start, but you'd need to modify it to:
                • Allow for custom domain configuration
                • Implement one of the certificate solutions mentioned above
                • Possibly add a script to automatically update SRV records via Cloudron's API
                1. Reducing Overhead:
                  Unlike Snikket, Prosody doesn't include a TURN/STUN server by default. You could either:
                  a) Use an external TURN/STUN service
                  b) Implement a lightweight TURN/STUN server as a separate Cloudron app

                To move forward:

                1. Fork the existing Cloudron-Prosody repo and start implementing these changes.
                2. Engage with Cloudron's development team about adding an option for apps to use the primary domain certificate. This would solve many of these issues at the platform level.
                3. Consider implementing a custom module for Prosody that interfaces with Cloudron's API for dynamic configuration and certificate management.

                This approach should address the specific technical challenges you're facing with implementing an XMPP server on Cloudron while taking advantage of Prosody's flexibility. The key will be integrating Prosody's configurability with Cloudron's app structure and API."

                1 Reply Last reply
                1
                • D Offline
                  D Offline
                  djxx
                  wrote on last edited by
                  #34

                  @girish - Given that the only blocker (that I know of so far) is the TLD certificate availability, would it be a decent workaround to package this entire thing as an application, and then run a one-time command to symlink the TLD certificate into the application directory? This would allow the sys admin to choose which application deserves access to the TLD certificate, ensure the app always has access to the latest certificate, and work around the current limitation of apps not being able to request the TLD cert.

                  1 Reply Last reply
                  2
                  • D Offline
                    D Offline
                    djxx
                    wrote on last edited by
                    #35

                    @girish - checking in again. I have another server I'm considering moving to Cloudron - but I need XMPP.

                    1 Reply Last reply
                    2
                    • girishG Offline
                      girishG Offline
                      girish
                      Staff
                      wrote on last edited by
                      #36

                      @djxx Just re-reading this thread again. From what I gathered, the app can be installed in app.domain.com but can use handles like @domain.com . For that matter, it can use handles like @handle.domain.com as well. All a matter of configuration . For this, the app requires certs of whatever the handle domain is.

                      I guess we need some sort of option field in the 'tls' addon - https://docs.cloudron.io/packaging/addons/#tls . But I am unable to quickly think of a way how to specify this in the manifest

                      1 Reply Last reply
                      2
                      • girishG Offline
                        girishG Offline
                        girish
                        Staff
                        wrote on last edited by
                        #37

                        Is https://github.com/DerekJarvis/cloudron-prosody still the latest code ? If I build that app, does it work?

                        1 Reply Last reply
                        0
                        • D Offline
                          D Offline
                          djxx
                          wrote on last edited by djxx
                          #38

                          I will take another look at building the custom app, as well as the TLS option and report back when I'm ready. 🙂

                          1 Reply Last reply
                          3
                          • D Offline
                            D Offline
                            djxx
                            wrote on last edited by
                            #39

                            Small update - made good progress. What's working so far:

                            • XMPP server starts up, messages can be sent/received
                              • this includes the pretty user@domain.com username
                            • LDAP Auth works, so users use their own accounts
                            • App health check

                            What doesn't work: anything related to HTTP endpoints (e.g. file uploads) . I've opened a ticket here: https://forum.cloudron.io/topic/13539/custom-app-httpport-not-being-proxied

                            1 Reply Last reply
                            4
                            • D Offline
                              D Offline
                              djxx
                              wrote on last edited by djxx
                              #40

                              Big update - I'm ready for your help @girish .

                              Repo: https://github.com/DerekJarvis/cloudron-prosody
                              Docker Image: derekjarvis/cloudron-prosody:20250406-042328-86345387d

                              What's working:

                              Everything.
                              07a69568-9079-4ac3-aa3d-49ccd4c84876-image.png

                              This is a full-fledged XMPP server with:

                              • Healthcheck
                              • TURN server for jingle calling (voice and video)
                              • Uses LDAP for auth and automatically works for all users
                              • Supports sending/receiving files and images
                              • Supports message carbons (sync messages between devices)
                              • Supports standard (pretty) accounts like user@domain.com

                              c7873765-208d-4a13-a665-f3dc6d1b7a06-image.png

                              374fbe93-3c8f-4699-b44d-4a1ca84f1bcd-image.png
                              (Direct TLS failing is intentional because it's deprecated and our upstream doesn't bother supporting it)

                              Approach:

                              I forked from a repository that has a good Prosody docker image with VERY secure defaults. I actually had to loosen a couple to make it more user friendly (like not requiring OMEMO). I added on the modules that make it even more useful (like HTTP upload for file attachments, TURN for jingle calls). I tried to make the majority of changes in our own files to make it easier to compare to upstream. I used Cloudron services (like LDAP, TURN) instead of running extra services in the container.

                              Help Needed:

                              There are a few VERY hacky things I had to do to make this work. Only one is a total blocker for real deployment by others, the others are all "nice to have" improvements.

                              TLD (Top-Level Domain) certs (blocker)

                              XMPP needs the TLD cert to allow the standard (and pretty) usernames like user@domain.com. Right now, there's no way for a Cloudron app to request the TLD cert. To work around this I did the following:

                              • Made a storage volume for the app
                              • Copied all the certs into the storage volume (yes, this is a very bad idea)
                                • cp -f /home/yellowtent/platformdata/nginx/cert/* /mnt/HC_Volume_102134826/app_xmpp/
                              • Have the app use the certs it needs and then delete everything else

                              Aliases needed (nice to have)

                              The app is installed under the "xmpp" domain, and 4 aliases must be defined in the app, and also in the DNS records:

                              • conference.domain.com
                              • proxy.domain.com
                              • pubsub.domain.com
                              • upload.domain.com

                              It would be great if the Manifest allowed us to specify additional aliases the app needs, and also added the DNS records for those if the Cloudron instance is using a DNS API

                              SRV Records (nice to have)

                              XMPP uses SRV records to give information about the XMPP servers for a domain. Specifically:

                              • _xmpp-client._tcp.domain.tld port 5222
                              • _xmpps-client._tcp.domain.tld port 5223
                              • _xmpp-server._tcp.domain.tld port 5269

                              Add these manually, and your app will work fine.

                              It would be ideal if Cloudron allowed specifying additional DNS records that should be created if the Cloudron instance is using a DNS API.

                              Admin users (nice to have)

                              I couldn't find a way to identify Cloudron Admin users through LDAP. Prosody supports specifying an LDAP query to indicate who is an admin of the XMPP server.

                              It would be ideal if there was an LDAP query that could identify Admin users, and then Prosody would mark those users as admins as well.

                              External IP for checks (nice to have)

                              Prosody has a very convenient check function which will check for common errors. One of the things it checks for is if it thinks it is reachable by checking the DNS records it uses against the IP addresses it knows it has. So in the Prosody config you can tell it the known IP addresses for the server, and the check function will compare that to the DNS records to confirm the server is reachable.

                              It would be ideal if we have an environment variable for the server's primary IP address. With this the checks would not show so many false positives.

                              TLD environment variable (nice to have)

                              Prosody needs to know the TLD it is serving. I did not find an environment variable for this, so I hacked one using bash:
                              export DOMAIN=${CLOUDRON_WEBADMIN_ORIGIN#https://my.}

                              It would be ideal if Cloudron exposed an environment variable for the TLD.

                              Other Comments

                              The #1 reason I use XMPP is for self-hosted private chat. The #2 reason is it's how I have a virtual phone number for SMS. I use https://jmp.chat to get a VERY CHEAP sms number and use XMPP on all my devices to communicate with people through SMS on convenient chat apps like Gajim and Conversations.

                              jdaviescoatesJ 1 Reply Last reply
                              8
                              • D djxx

                                Big update - I'm ready for your help @girish .

                                Repo: https://github.com/DerekJarvis/cloudron-prosody
                                Docker Image: derekjarvis/cloudron-prosody:20250406-042328-86345387d

                                What's working:

                                Everything.
                                07a69568-9079-4ac3-aa3d-49ccd4c84876-image.png

                                This is a full-fledged XMPP server with:

                                • Healthcheck
                                • TURN server for jingle calling (voice and video)
                                • Uses LDAP for auth and automatically works for all users
                                • Supports sending/receiving files and images
                                • Supports message carbons (sync messages between devices)
                                • Supports standard (pretty) accounts like user@domain.com

                                c7873765-208d-4a13-a665-f3dc6d1b7a06-image.png

                                374fbe93-3c8f-4699-b44d-4a1ca84f1bcd-image.png
                                (Direct TLS failing is intentional because it's deprecated and our upstream doesn't bother supporting it)

                                Approach:

                                I forked from a repository that has a good Prosody docker image with VERY secure defaults. I actually had to loosen a couple to make it more user friendly (like not requiring OMEMO). I added on the modules that make it even more useful (like HTTP upload for file attachments, TURN for jingle calls). I tried to make the majority of changes in our own files to make it easier to compare to upstream. I used Cloudron services (like LDAP, TURN) instead of running extra services in the container.

                                Help Needed:

                                There are a few VERY hacky things I had to do to make this work. Only one is a total blocker for real deployment by others, the others are all "nice to have" improvements.

                                TLD (Top-Level Domain) certs (blocker)

                                XMPP needs the TLD cert to allow the standard (and pretty) usernames like user@domain.com. Right now, there's no way for a Cloudron app to request the TLD cert. To work around this I did the following:

                                • Made a storage volume for the app
                                • Copied all the certs into the storage volume (yes, this is a very bad idea)
                                  • cp -f /home/yellowtent/platformdata/nginx/cert/* /mnt/HC_Volume_102134826/app_xmpp/
                                • Have the app use the certs it needs and then delete everything else

                                Aliases needed (nice to have)

                                The app is installed under the "xmpp" domain, and 4 aliases must be defined in the app, and also in the DNS records:

                                • conference.domain.com
                                • proxy.domain.com
                                • pubsub.domain.com
                                • upload.domain.com

                                It would be great if the Manifest allowed us to specify additional aliases the app needs, and also added the DNS records for those if the Cloudron instance is using a DNS API

                                SRV Records (nice to have)

                                XMPP uses SRV records to give information about the XMPP servers for a domain. Specifically:

                                • _xmpp-client._tcp.domain.tld port 5222
                                • _xmpps-client._tcp.domain.tld port 5223
                                • _xmpp-server._tcp.domain.tld port 5269

                                Add these manually, and your app will work fine.

                                It would be ideal if Cloudron allowed specifying additional DNS records that should be created if the Cloudron instance is using a DNS API.

                                Admin users (nice to have)

                                I couldn't find a way to identify Cloudron Admin users through LDAP. Prosody supports specifying an LDAP query to indicate who is an admin of the XMPP server.

                                It would be ideal if there was an LDAP query that could identify Admin users, and then Prosody would mark those users as admins as well.

                                External IP for checks (nice to have)

                                Prosody has a very convenient check function which will check for common errors. One of the things it checks for is if it thinks it is reachable by checking the DNS records it uses against the IP addresses it knows it has. So in the Prosody config you can tell it the known IP addresses for the server, and the check function will compare that to the DNS records to confirm the server is reachable.

                                It would be ideal if we have an environment variable for the server's primary IP address. With this the checks would not show so many false positives.

                                TLD environment variable (nice to have)

                                Prosody needs to know the TLD it is serving. I did not find an environment variable for this, so I hacked one using bash:
                                export DOMAIN=${CLOUDRON_WEBADMIN_ORIGIN#https://my.}

                                It would be ideal if Cloudron exposed an environment variable for the TLD.

                                Other Comments

                                The #1 reason I use XMPP is for self-hosted private chat. The #2 reason is it's how I have a virtual phone number for SMS. I use https://jmp.chat to get a VERY CHEAP sms number and use XMPP on all my devices to communicate with people through SMS on convenient chat apps like Gajim and Conversations.

                                jdaviescoatesJ Offline
                                jdaviescoatesJ Offline
                                jdaviescoates
                                wrote on last edited by
                                #41

                                @djxx great work! Many thanks for your efforts! 🙏 hopefully @staff can assist to get this over the line and into the app store! 🙏

                                I use Cloudron with Gandi & Hetzner

                                1 Reply Last reply
                                0
                                • nebulonN Offline
                                  nebulonN Offline
                                  nebulon
                                  Staff
                                  wrote on last edited by
                                  #42

                                  @djxx very nice! I just tried to quickly test this and building from your repo, the app fails to start with the following error:

                                  cp: cannot stat '/media/Extra Storage/app_xmpp/*': No such file or directory
                                  

                                  probably some oversight there, but don't have time to dig into this just now.

                                  D 1 Reply Last reply
                                  1
                                  • nebulonN nebulon

                                    @djxx very nice! I just tried to quickly test this and building from your repo, the app fails to start with the following error:

                                    cp: cannot stat '/media/Extra Storage/app_xmpp/*': No such file or directory
                                    

                                    probably some oversight there, but don't have time to dig into this just now.

                                    D Offline
                                    D Offline
                                    djxx
                                    wrote on last edited by
                                    #43

                                    @nebulon - Correct. You would need to make a volume called "Extra Storage", mount it onto the app, and have a folder under it called app_xmpp where you copy the sub-domain and TLD certs you need (I just copied all of them). This is an ugly workaround for the TLD cert not being available to the app through the manifest configuration.

                                    You would also need to add a few alias domains and DNS records manually.

                                    1 Reply Last reply
                                    2
                                    • D Offline
                                      D Offline
                                      djxx
                                      wrote on last edited by djxx
                                      #44

                                      I guess some clear set up instructions would help 🙂

                                      • install the app to the 'xmpp' subdomain
                                      • add extra DNS CNAME/A records pointing to the same server:
                                        • pubsub
                                        • proxy
                                        • upload
                                        • conference
                                      • add these domains as aliases for the app
                                      • add DNS SRV records:
                                        • _xmpp-client._tcp.domain.tld port 5222
                                        • _xmpps-client._tcp.domain.tld port 5223
                                        • _xmpp-server._tcp.domain.tld port 5269
                                      • make a storage volume called "Extra Storage"
                                      • mount the storage volume to the app
                                      • copy certs into the storage under the subdirectory app_xmpp
                                        • for my server, the command looks like this (run in cloudron directly, not in the app terminal):
                                        • cp -f /home/yellowtent/platformdata/nginx/cert/* /mnt/HC_Volume_102134826/app_xmpp/
                                      • restart the app to make sure it's starting up with all pieces in place (extra domains, DNS records, and certs)

                                      Then you can check for compliance with these two tools:

                                      • https://compliance.conversations.im
                                      • https://connect.xmpp.net/
                                      1 Reply Last reply
                                      3
                                      • nebulonN Offline
                                        nebulonN Offline
                                        nebulon
                                        Staff
                                        wrote on last edited by
                                        #45

                                        I took the time to take a bit closer into the package. There is a long way to go to make it compliant with Cloudron packaging. It is a great start and we don't provide good information on what is expected from Cloudron packages, so this is mostly our fault.

                                        For a start, you already added the tls addon, which does provide the certs in /etc/certs/ using that instead of the extra volume mount will ensure the app gets restarted and will pick up the correct certs if they get renewed. I am playing a bit from your package to hopefully get this working.

                                        One question is, apparently certs for the root domain are also required, even though no DNS records for that are? This can be solved by also adding the root domain as an alias to the app.

                                        For the extra required DNS records, we have to see if and how we can integrate this in the platform to support those. We already have some well-known type records, maybe it fits there.

                                        Otherwise there are naturally discrepancies elsewhere, given that this started (as far as I can tell) from some upstream Dockerimage which will not fit, but we can get through one by one. The first I noticed was, that currently it doesn't work with the Cloudron app debug mode, since it uses ENTRYPOINT in Dockerfile, that was easy to change by relying only on CMD

                                        D 1 Reply Last reply
                                        1
                                        • nebulonN Offline
                                          nebulonN Offline
                                          nebulon
                                          Staff
                                          wrote on last edited by
                                          #46

                                          I've pushed my changes as a PR https://github.com/DerekJarvis/cloudron-prosody/pull/1

                                          No need to merge that, just to give some idea about the certs handling. The alias domains still need to be manually setup by the user, so maybe we need some platform feature in the future for this.

                                          jdaviescoatesJ 1 Reply Last reply
                                          2
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Bookmarks
                                          • Search