ejabberd
Overview
ejabberd is a robust, scalable, open source XMPP (Jabber) server for real-time messaging. It supports one-to-one chat, presence, group chat rooms (MUC), publish-subscribe and server-to-server federation.
This SecureAnyCloud image gives you a private chat server that any standard XMPP client can connect to, with a built-in web admin console for managing virtual hosts, users and rooms. It installs ejabberd 26.04 from the official ProcessOne package, which bundles its own Erlang runtime, and runs it as the dedicated ejabberd system service.
What you get:
ejabberd26.04 installed from the official ProcessOne package and run as the ejabberd system service- The built-in Mnesia database (no external database required) on a dedicated Azure data disk at
/var/lib/ejabberd. It holds your users, rooms and rosters. - The web admin console bound to the loopback connector
127.0.0.1:5280, with nginx on port 80 reverse proxying to it. nginx adds the WebSocket upgrade that the/wsand/boshendpoints (XMPP over WebSocket and BOSH) require. - Port 80 serving an unauthenticated
/healthzendpoint for load balancer probes - XMPP client-to-server connections on port 5222 (c2s, STARTTLS) and server-to-server federation on port 5269 (s2s)
- A unique admin account generated on first boot of every VM, the full JID
admin@localhost, recorded in a root-only file ejabberd.serviceandnginx.serviceas enabled, active systemd units- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a reasonable starting size. Choose a larger size for more concurrent users and rooms.
Configure the network security group (NSG) to allow these inbound ports:
22/tcpfrom your management network80/tcpfor the web admin, plus443/tcpif you add TLS5222/tcpfor XMPP clients5269/tcpfor server-to-server federation
The web admin is served over plain HTTP by default. For production, put your own domain and a trusted certificate in front of it (see Maintenance).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for ejabberd by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Review the dedicated data disk on the Disks tab, then select Review + create and Create. After the VM is created, add inbound rules for 5222 (XMPP clients) and 5269 (federation).
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:ejabberd-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name ejabberd \
--image sac1647283583153:ejabberd-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name ejabberd --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name ejabberd --port 5222 --priority 1020
az vm open-port --resource-group <your-rg> --name ejabberd --port 5269 --priority 1030Step 3 - Connect to your VM
Connect over SSH as the admin user you created (azureuser in the CLI example):
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
Run these commands to check both services and the listening ports:
systemctl is-active ejabberd.service nginx.service
sudo -u ejabberd -H /usr/sbin/ejabberdctl status ss -tlnp | grep -E '5222|5269|5280'Both services report active, and ejabberdctl status reports that the node is started. ejabberd listens on port 5222 for XMPP clients and 5269 for federation. The web admin listens only on the loopback address 127.0.0.1:5280, behind nginx on port 80.
Step 5 - Retrieve your admin password
The first boot of your VM generates a unique ejabberd admin password and writes it to a root-only file. Read it with sudo:
sudo cat /root/ejabberd-credentials.txtThe file contains EJABBERD_ADMIN_JID (the full JID admin@localhost), EJABBERD_PASSWORD and the web admin URL. Store the password somewhere safe. The file is mode 0600 and owned by root, so only an administrator can read it.
The Mnesia database that holds your users and rooms lives on the dedicated Azure data disk mounted at /var/lib/ejabberd.
Step 6 - Confirm the health endpoints
nginx serves an unauthenticated health endpoint for load balancers and probes. It challenges the web admin for authentication. Check both:
curl -s http://localhost/healthz
curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://localhost/healthz
curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://localhost/admin//healthz returns ok with HTTP 200 and never requires authentication, so it is safe for an Azure Load Balancer health probe. The web admin at /admin/ returns HTTP 401 until you supply credentials.
Step 7 - Verify authentication from the command line
The web admin uses HTTP Basic Auth with the full JID admin@localhost as the username. The check below sends the correct per-VM password and reaches the console (HTTP 200), then sends a wrong password and is rejected (HTTP 401).
The command embeds your unique password, so run it interactively rather than from a script. Replace <EJABBERD_PASSWORD> with the value of EJABBERD_PASSWORD from Step 5:
curl -s -o /dev/null -w 'correct password -> HTTP %{http_code}\n' \
-u 'admin@localhost:<EJABBERD_PASSWORD>' http://localhost/admin/
curl -s -o /dev/null -w 'wrong password -> HTTP %{http_code}\n' \
-u 'admin@localhost:wrong' http://localhost/admin/The correct per-VM password prints HTTP 200, which means it reached the admin console. The wrong password prints HTTP 401, which means it was rejected.
Step 8 - Sign in to the web admin
Browse to http://<vm-public-ip>/admin/. When the browser shows an HTTP authentication prompt, enter the full JID admin@localhost as the username and the password from Step 5.
You land on the ejabberd Web Admin, which lists your virtual hosts and cluster nodes. From here you manage users, rooms, access rules and server internals.
Step 9 - Open your virtual host
Click the localhost virtual host to see its overview: the number of registered users, online users, shared rosters and the modules serving the host. localhost is the default served domain. To serve a real public domain, see Maintenance.
Every user JID that belongs to this host, for example alice@localhost, is managed under this virtual host.
Step 10 - Register users
Open Users under the virtual host to list existing accounts and register new ones. Enter a username and password to create a JID such as alice@localhost. That user can then sign in from any XMPP client.
You can also register users from the command line:
sudo -u ejabberd -H /usr/sbin/ejabberdctl register alice localhost 'a-strong-password'Step 11 - Inspect the node
Open the node (for example ejabberd@localhost) to see server internals: the database tables, backend statistics, the running modules and the Erlang virtual machine. Use this page to confirm the Mnesia backend and monitor the health of the node.
Step 12 - Connect an XMPP client
Point any XMPP client at your server, for example Gajim, Conversations, Dino or Pidgin. Sign in with a JID you registered, such as alice@localhost, and the password you set.
Set the connection server or host to the VM's public IP address and use port 5222. The appliance requires STARTTLS on client connections.
ejabberd federates with other servers over port 5269 (server to server). Create group chat rooms from a client that supports Multi User Chat, or manage them from the web admin.
Step 13 - Confirm data lives on the dedicated disk
ejabberd stores its data under /var/lib/ejabberd on the dedicated Azure data disk. This is the Mnesia database that holds your registered users, rooms, rosters and offline messages. The data survives OS changes and the disk can be resized independently. Confirm the mount:
findmnt /var/lib/ejabberdThe mount is backed by a separate Azure data disk that is captured into the image and re-provisioned on every VM.
Maintenance
- Password. The admin password is set on first boot. To change it, sign in to the web admin, or run
sudo -u ejabberd -H /usr/sbin/ejabberdctl change_password admin localhost '<new-password>'. - Serve a real domain. The default served XMPP domain is
localhost. For production, set your public domain in thehosts:list in/opt/ejabberd/conf/ejabberd.yml, register anadmin@<yourdomain>account, add it to theadminACL, and restartejabberd.service. Configure DNS SRV records (_xmpp-client._tcpand_xmpp-server._tcp) for federation. - TLS and certificates. The appliance serves the web admin over plain HTTP on port 80, and ejabberd generates a self-signed certificate for client STARTTLS. For production, point a DNS name at the VM and obtain a trusted certificate, for example with certbot and Let's Encrypt. List it under
certfiles:inejabberd.yml, and front the web admin with nginx TLS on port 443. - Chat rooms (MUC). Multi User Chat is enabled. Create and administer rooms from an XMPP client or the web admin. Rooms and their archives are stored in the Mnesia database on the data disk.
- Federation. Server-to-server is enabled on port 5269, with STARTTLS optional. Open the port in your NSG to chat with users on other XMPP servers.
- Upgrades. ejabberd is installed under
/opt/ejabberd. Upgrade with the ProcessOne package and restartejabberd.service. Your data under/var/lib/ejabberdis preserved. - Storage. All ejabberd state lives under
/var/lib/ejabberdon the data disk. Back up that volume to protect your users, rooms and history. - Security patches. Unattended-upgrades stays enabled, so the OS keeps receiving security updates automatically.
Support
SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.
Deploy on Azure
Launch ejabberd XMPP Server on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
ejabberd is a robust, massively scalable, self-hosted XMPP (Jabber) real-time messaging server. It powers instant messaging, presence, multi-user chat rooms (MUC), publish-subscribe and push for your own users and applications. It speaks the open XMPP standard, so any standards-compliant chat client can connect.
This SecureAnyCloud image runs ejabberd on your own AWS infrastructure and includes ejabberd's built-in web administration console.
What you get:
ejabberdinstalled from the official ProcessOne binary package, which bundles its own Erlang/OTP runtime, and run under a dedicated ejabberd service account managed by systemd- The web admin console bound to the loopback interface on port
5280and reached through nginx. nginx listens on port 80 and reverse-proxies to the console with the WebSocket upgrade that XMPP-over-WebSocket and BOSH clients require. - The client-to-server port
5222and the server-to-server port5269, exposed directly - A dedicated EBS data volume mounted at
/var/lib/ejabberd. It holds ejabberd's configuration, its Mnesia database of accounts, rosters and rooms, and its generated certificate, and it is resizable independently of the operating system disk. - A one-shot first-boot service that generates a fresh administrator account with a password unique to the instance and registers it as
admin@localhostwith server-administration rights. The service also generates a fresh self-signed certificate and records the credentials in/root/ejabberd-credentials.txtwith mode 0600. - No shared or default messaging account and no reused certificate in the image
Prerequisites
Before you deploy this image, make sure you have:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network, inbound port 80 (and 443 if you add HTTPS) from the networks your operators use to reach the web admin, and inbound ports 5222 and 5269 from the networks your XMPP clients and federated servers connect from
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line
Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for ejabberd. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of t3.small or larger. Choose your EC2 key pair under Key pair (login).
Under Network settings, select your VPC and subnet. Create or select a security group that allows inbound port 22 from your management network, port 80 from your operators, and ports 5222 and 5269 from your clients and federated servers. Leave the root volume at the default size or larger. The image adds a separate data volume for the ejabberd database and certificate automatically.
Select Launch instance. First-boot initialisation generates the certificate and the administrator account. It takes about a minute after the instance state becomes Running and the status checks pass.
Launch the Instance from the AWS CLI
Run the following command to launch an instance from the SecureAnyCloud ejabberd Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing and <key-name> with your EC2 key pair name. Replace <subnet-id> with your subnet ID and <security-group-id> with a security group that opens ports 22, 80, 5222 and 5269 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type t3.small \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":20,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=ejabberd-01}]'On success, the command prints a JSON document. Note the instance ID. Once the instance is running, retrieve its public address with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Connect and Retrieve the Administrator Credentials
Connect over SSH with the key pair you selected and the public IP address from step 2. For the ejabberd 26.04 on Ubuntu 24.04 AMI, the SSH login user is ubuntu.
ssh -i /path/to/your-key.pem ubuntu@<public-ip>The first boot writes the administrator credentials to a root-only file. Read them with:
sudo cat /root/ejabberd-credentials.txtThe file contains the web admin URL, the administrator Jabber ID (admin@localhost) and the password unique to this instance:
EJABBERD_WEB_ADMIN_URL=http://<public-ip>/admin/ EJABBERD_ADMIN_JID=admin@localhost EJABBERD_PASSWORD=<generated-password>To confirm that the server is running, use ejabberdctl at any time:
sudo ejabberdctl statusThe node ejabberd@localhost is started with status: started ejabberd 26.4.0 is running in that nodeSign In to the Web Admin Console
Open http://<public-ip>/admin/ in your browser. The web admin uses HTTP Basic authentication. Enter the full Jabber ID admin@localhost as the user name and the generated password.
The console opens on the ejabberd Web Admin home. From there you can browse your XMPP virtual hosts, Erlang nodes and multi-user chat.
Under Virtual Hosts, select your virtual host (localhost) to open its administration page. It links to users, online users, announcements, multi-user chat, shared roster groups and statistics.
Register Users
Open Users under your virtual host. Enter a user name and password under Register, then choose Register to create an XMPP account. The registered accounts are listed below.
You can also register users from the command line, which suits scripting and bulk provisioning:
sudo ejabberdctl register alice localhost 'a-strong-password'
sudo ejabberdctl registered_users localhostCreate Multi-User Chat Rooms
Open Multi-User Chat under your virtual host to reach the conference service (conference.localhost). Here you create and administer group chat rooms.
To create a room from the command line:
sudo ejabberdctl create_room general conference.localhost localhost
sudo ejabberdctl muc_online_rooms globalConnect an XMPP Client
Any standards-compliant XMPP client can connect, for example Gajim, Conversations, Dino or Psi. Point the client at your server address. Use a Jabber ID of the form user@localhost, or your real domain once you set one (see step 8), and the password you registered.
The server accepts connections on these ports:
- 5222: client-to-server (c2s), for user logins
- 5269: server-to-server (s2s), for federation with other XMPP servers
Web clients can also use XMPP over WebSocket and BOSH, which nginx serves on port 80 at /ws and /bosh.
Set a Real Domain and Certificate for Production
The appliance ships with a single XMPP virtual host, localhost, and a self-signed certificate, so it works out of the box. For production, set your real XMPP domain and install a trusted certificate so that remote users and other servers can reach and trust your server.
Edit the hosts list in the configuration file on the data volume:
sudo nano /var/lib/ejabberd/conf/ejabberd.yml
# set hosts: to <your-domain>hosts: - chat.example.comPoint DNS at the instance with an A record for your domain, plus the XMPP SRV records _xmpp-client._tcp on 5222 and _xmpp-server._tcp on 5269. Obtain a certificate for the domain, for example with Let's Encrypt, and set certfiles to it. Then reload the configuration and register your administrator on the new host:
sudo ejabberdctl reload_config
sudo ejabberdctl register admin <your-domain> '<a-strong-password>'Add admin@chat.example.com to the admin ACL in ejabberd.yml so that it can manage the new host, then reload again.
Health Endpoint
nginx serves an unauthenticated health endpoint for load balancer and uptime checks:
curl http://<public-ip>/healthzokWhere Your Data Lives
ejabberd's configuration, its Mnesia database and its certificate live on a dedicated EBS data volume mounted at /var/lib/ejabberd. The database holds accounts, rosters, multi-user chat rooms, PubSub nodes and offline messages. The binary installer's /opt/ejabberd path is a symlink onto this volume, so every stateful path resolves onto the dedicated disk:
findmnt -no SOURCE,TARGET,FSTYPE /var/lib/ejabberd/dev/nvme1n1 /var/lib/ejabberd ext4Because the data volume is separate from the operating system disk, you can snapshot it for backup and grow it independently. The server runs under systemd. Check or control it with systemctl status ejabberd, and manage the application with sudo ejabberdctl.
Maintenance
- Back up the data volume with an EBS snapshot, or export accounts and rooms with
ejabberdctlcommands. - Restart the server with
sudo systemctl restart ejabberdand nginx withsudo systemctl restart nginx. - Reload the configuration after you edit
ejabberd.ymlby runningsudo ejabberdctl reload_config. Most changes need no restart. - Upgrade the operating system with
sudo apt-get update && sudo apt-get upgrade.
Support
SecureAnyCloud provides 24/7 technical support by email and chat. We can help with deployment, XMPP domain and certificate configuration, client and federation setup, chat-room and access-control design, clustering, storage and upgrade planning. Contact support through the channel listed on your AWS Marketplace subscription.
Deploy on AWS
Launch ejabberd on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com