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
60 Posts 6 Posters 4.6k 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

      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 Away
        nebulonN Away
        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 Away
              nebulonN Away
              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 Away
                nebulonN Away
                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
                • nebulonN nebulon

                  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 Offline
                  jdaviescoatesJ Offline
                  jdaviescoates
                  wrote on last edited by
                  #47

                  @nebulon said in XMPP Server - Prosody:

                  The alias domains still need to be manually setup by the user, so maybe we need some platform feature in the future for this.

                  Don't we already have this for e.g. apps like Loomio?

                  I use Cloudron with Gandi & Hetzner

                  1 Reply Last reply
                  0
                  • nebulonN Away
                    nebulonN Away
                    nebulon
                    Staff
                    wrote on last edited by
                    #48

                    loomio and others like minio have multiple http ports (which are routed through the reverse proxy). If I understand the xmpp use-case correctly, then those are just alias endpoints not serving any http content. Even the current main domain will just produce a 404 when hit with a browser. The alias use is more like a bit of a workaround to get DNS setup as well as get valid certs.

                    1 Reply Last reply
                    1
                    • nebulonN nebulon

                      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 Offline
                      D Offline
                      djxx
                      wrote on last edited by
                      #49

                      @nebulon Thanks for taking a look through. I am certainly open to making changes to make it a compliant package - I just don't know what those changes are.

                      I didn't realize that the TLD could be added as an alias which would give the cert. I was using /etc/certs before I did the hacky workaround to get the TLD. I will try the approach you mentioned and make sure things are still working.

                      One question is, apparently certs for the root domain are also required, even though no DNS records for that are?

                      Correct. The XMPP specification uses the SRV records to point to a specific server. It does need the cert to validate usernames like user@domain.com even if you chose to have the XMPP server somewhere else completely.

                      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.

                      Can you tell me a bit more about this? I changed it to use the Cloudron base, and confirmed that all the actions it does to build the server are successful. I did my best to follow putting data under /app/data, and runtime files under /run, according to the documentation.

                      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.

                      This would be nice, but it's really not that difficult (compared to the entirety of setting up an XMPP server). I think if the package was installable and the only extra steps are some DNS changes, it'd still be very easy for people who want XMPP to do.

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

                        @nebulon - I just tried the alias approach, but it gives the error alias location 'domain.tld' is in use. So it seems the cert workaround will still be needed until there is a manifest option to get the TLD cert without using the alias

                        1 Reply Last reply
                        1
                        • nebulonN Away
                          nebulonN Away
                          nebulon
                          Staff
                          wrote on last edited by
                          #51

                          Yes, we have to add this to the platform as a feature as well as think about how to make the DNS setup for those extra domains required. We have a policy that apps should "work" after installation. Do you know if there is a way that maybe those extra (sub)domains and thus their certs can be optional, just limiting the functionality of the app?

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

                            The root cert will always be needed to get user@domain.com addresses, and not having the other sub-domains would make the app basically unusable. The extra sub-domains are for things like: uploading files, proxying connections when a direct connection is unavailable, and for allowing people from other serveres to contact users on your XMPP instance. So, if all the extra domains were removed you would only have an XMPP chat that works locally on your server, and without pictures. These limitations defeat the person of having XMPP, in my opinion.

                            After looking again, it seems we could drop the "proxy" sub-domain since we're using Cloudron's TURN server (I would need to test). But there's still a non-zero number of extra domains needed, as well as the TLD cert.

                            1 Reply Last reply
                            1
                            • nebulonN Away
                              nebulonN Away
                              nebulon
                              Staff
                              wrote on last edited by
                              #53

                              Agree that those are required for a real instance, I was just trying to understand if we can provide a package where the app does not crash on initial startup until those are set up.

                              All in all since we at least need changes to the TLS addon to also provide the root domain certs, we are looking at least to a package release after the next Cloudron version only. Just to keep expectations clear.

                              D 1 Reply Last reply
                              1
                              • nebulonN nebulon

                                Agree that those are required for a real instance, I was just trying to understand if we can provide a package where the app does not crash on initial startup until those are set up.

                                All in all since we at least need changes to the TLS addon to also provide the root domain certs, we are looking at least to a package release after the next Cloudron version only. Just to keep expectations clear.

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

                                @nebulon understood. If needed, I'm sure we could make it not crash, even if it's not really a functional XMPP server. And for me I'm at least happy I have a way to run XMPP on my server. I'm just trying to share the work with others.

                                When is the next version scheduled for release?

                                1 Reply Last reply
                                1
                                • nebulonN Away
                                  nebulonN Away
                                  nebulon
                                  Staff
                                  wrote on last edited by
                                  #55

                                  We are currently quite busy with Cloudron 9 development, lets see if we can get some of those things still in.

                                  After reading up a bit on prosody docs, I still dont fully understand what we should do with the default location and what we could serve up as http (currently it shows a 404 error page for example). I saw there is also BOSH which is intended for http, so maybe that can be placed there instead, but so far I don't have a good grip on prosody's use of domains, certs and ports.

                                  D 1 Reply Last reply
                                  0
                                  • nebulonN nebulon

                                    We are currently quite busy with Cloudron 9 development, lets see if we can get some of those things still in.

                                    After reading up a bit on prosody docs, I still dont fully understand what we should do with the default location and what we could serve up as http (currently it shows a 404 error page for example). I saw there is also BOSH which is intended for http, so maybe that can be placed there instead, but so far I don't have a good grip on prosody's use of domains, certs and ports.

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

                                    @nebulon In general, XMPP isn't going to actually serve any web pages. I installed an extra module for health checking because Cloudron requires it - but there's no reason it needs to be exposed externally. BOSH may use HTTP, but it doesn't serve responses that can be interpreted as web pages.

                                    Personally, I don't think it hurts that there's a 404 on an HTTP/S port for an application that doesn't serve HTTP. Putting up a big page like "You found an XMPP server!" just invites trouble from the bad people on the internet.

                                    1 Reply Last reply
                                    0
                                    • nebulonN Away
                                      nebulonN Away
                                      nebulon
                                      Staff
                                      wrote on last edited by
                                      #57

                                      Thanks for that input. I think what we really need to add is a way to run apps as headless services. We already have a few of those like game servers and synapse (matrix) which have to serve up a placeholder page. That is not ideal indeed. After Cloudron 9 we will also look into other things like maybe databases, they would have very similar requirements then.

                                      Sorry that this is not yet implemented but we will get there in the future, so it is already great to collect requirements for such service type apps like prosody. This helps to avoid developing the wrong things on the platform side 🙂

                                      1 Reply Last reply
                                      1
                                      • robiR Offline
                                        robiR Offline
                                        robi
                                        wrote on last edited by
                                        #58

                                        Doesn't Matrix also require something on the root domain? Isn't that where the .well-known endpoint lives?

                                        Something similar can be had?

                                        @djxx, was the architecture chosen to use subdomains vs different ports?

                                        If we're clever with the reverse proxy or with the main app server that listens to connections, it can ferry connections for other services by the request type or layer it needs to access, avoiding the need for extra ports or subdomains.

                                        As for the HTTP page, why not make it multi-useful. For example, by default it's just a Cloudron OIDC login button and then per app it's configured what it does.. for backend services it could be a simple CLI stats page in HTML, or even a web terminal. That way it's flexible and useful to the admin, users, packaging and platform maintainers.

                                        What else would be useful there?

                                        Conscious tech

                                        D 1 Reply Last reply
                                        0
                                        • robiR robi

                                          Doesn't Matrix also require something on the root domain? Isn't that where the .well-known endpoint lives?

                                          Something similar can be had?

                                          @djxx, was the architecture chosen to use subdomains vs different ports?

                                          If we're clever with the reverse proxy or with the main app server that listens to connections, it can ferry connections for other services by the request type or layer it needs to access, avoiding the need for extra ports or subdomains.

                                          As for the HTTP page, why not make it multi-useful. For example, by default it's just a Cloudron OIDC login button and then per app it's configured what it does.. for backend services it could be a simple CLI stats page in HTML, or even a web terminal. That way it's flexible and useful to the admin, users, packaging and platform maintainers.

                                          What else would be useful there?

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

                                          @robi I'm not an expert, but I did do some research on this to respond to Nebulon above. The main thing to note here is that the XMPP protocol expects different domains for different functions. So yes - it's an architectural choice that is mostly beyond our control. Each subdomain represents a different module, and the modules talk to each other (and other servers). They need a way to identify themselves, and they use the domain.

                                          I did some reading and it seems it is theoretically possible to make a server that utilizes different ports to differentiate the modules under a single sub-domain, but this would require tweaking and re-compiling an XMPP server.

                                          Even if this was done, and all XMPP protocols followed, there's always the chance that some not-fully-compliant client that works with every well known XMPP server would not work with ours because we've chosen to deviate so far from the norm, while still technically following the standards. Making these upstream changes would require someone much more familiar with XMPP servers than me.

                                          While I look forward to Cloudron allowing us to package more complex services, I think XMPP is in a pretty good place for the above-average admin; it currently takes less than 5 minutes to set it up. I will probably end up making a cron job to sync the certs into my app's storage volume when I deploy this to production. If I think it's useful to others, and Cloudron 9 isn't out yet, I'll share it here.

                                          robiR 1 Reply Last reply
                                          3
                                          • D djxx

                                            @robi I'm not an expert, but I did do some research on this to respond to Nebulon above. The main thing to note here is that the XMPP protocol expects different domains for different functions. So yes - it's an architectural choice that is mostly beyond our control. Each subdomain represents a different module, and the modules talk to each other (and other servers). They need a way to identify themselves, and they use the domain.

                                            I did some reading and it seems it is theoretically possible to make a server that utilizes different ports to differentiate the modules under a single sub-domain, but this would require tweaking and re-compiling an XMPP server.

                                            Even if this was done, and all XMPP protocols followed, there's always the chance that some not-fully-compliant client that works with every well known XMPP server would not work with ours because we've chosen to deviate so far from the norm, while still technically following the standards. Making these upstream changes would require someone much more familiar with XMPP servers than me.

                                            While I look forward to Cloudron allowing us to package more complex services, I think XMPP is in a pretty good place for the above-average admin; it currently takes less than 5 minutes to set it up. I will probably end up making a cron job to sync the certs into my app's storage volume when I deploy this to production. If I think it's useful to others, and Cloudron 9 isn't out yet, I'll share it here.

                                            robiR Offline
                                            robiR Offline
                                            robi
                                            wrote on last edited by
                                            #60

                                            @djxx Appreciate the response.

                                            We already have some apps that require a secondary domain on the front end, but that isn't necessarily the case for the backend. We just need Nginx to route things as expected by the clients, etc.

                                            Glad you're here, packaging and interested in this stuff working.

                                            Conscious tech

                                            1 Reply Last reply
                                            1
                                            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