Skip to content

Deploying ejabberd

Introduction

ejabberd is a robust, scalable, and extensible XMPP (Extensible Messaging and Presence Protocol) server written in Erlang. Used by organizations worldwide, from small teams to platforms with millions of users, ejabberd provides reliable instant messaging, presence information, and real-time communication capabilities.

Originally developed in 2002, ejabberd has matured into one of the most trusted XMPP servers available. Its Erlang foundation provides exceptional concurrency and fault tolerance, making it capable of handling massive user bases while maintaining low latency and high availability. The server supports modern messaging features including group chats, file transfers, voice and video calls, and message archiving.

Key highlights of ejabberd:

  • Scalability: Handle millions of concurrent users with clustering support
  • Reliability: Erlang’s fault-tolerant design ensures high availability
  • XMPP Compliance: Full support for core XMPP specifications and extensions
  • Federation: Connect with other XMPP servers across the internet
  • Multi-Protocol: Support for XMPP, MQTT, SIP, and WebSocket
  • Multi-User Chat: Group chat rooms with moderation and persistence
  • Message Archive: Server-side message storage for offline access
  • Push Notifications: Mobile push support for iOS and Android
  • LDAP/OAuth: Enterprise authentication integration
  • Web Admin: Browser-based administration interface
  • 100% Open Source: GPL licensed with commercial support available

This guide walks through deploying ejabberd on Klutch.sh, configuring XMPP services, and managing your instant messaging platform.

Why Deploy ejabberd on Klutch.sh

Deploying ejabberd on Klutch.sh provides several advantages for real-time communication:

Simplified Deployment: Klutch.sh handles container orchestration while you focus on messaging configuration.

Data Ownership: Keep all messages and user data on your own infrastructure.

Persistent Storage: Attach volumes for message archives and user data that persist securely.

Scalable Resources: Allocate resources based on your user base and scale as needed.

Custom Domains: Use your own domain for professional XMPP addresses.

Always-On Availability: Your messaging server remains accessible 24/7 for real-time communication.

Prerequisites

Before deploying ejabberd on Klutch.sh, ensure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your configuration
  • A domain name with DNS control
  • TLS certificates for your domain
  • Basic understanding of XMPP protocol concepts
  • (Optional) An XMPP client for testing

Understanding ejabberd Architecture

ejabberd uses Erlang’s OTP framework for reliability:

Erlang BEAM: The virtual machine provides lightweight processes and fault tolerance.

Mnesia Database: Built-in distributed database for user data and configurations.

External Database: Optional PostgreSQL or MySQL for larger deployments.

Module System: Modular architecture allows enabling specific features as needed.

Clustering: Multiple nodes can form a cluster for high availability.

Preparing Your Repository

Create a GitHub repository with your ejabberd configuration.

Repository Structure

ejabberd-deploy/
├── Dockerfile
├── config/
│ └── ejabberd.yml
├── scripts/
│ └── entrypoint.sh
└── .dockerignore

Creating the Dockerfile

Create a Dockerfile for your ejabberd deployment:

FROM ejabberd/ecs:latest
# Copy configuration
COPY config/ejabberd.yml /home/ejabberd/conf/ejabberd.yml
# Copy entrypoint script
COPY scripts/entrypoint.sh /entrypoint.sh
USER root
RUN chmod +x /entrypoint.sh
USER ejabberd
# Create directories
RUN mkdir -p /home/ejabberd/database /home/ejabberd/upload
# Expose ports
# XMPP client connections
EXPOSE 5222
# XMPP client connections (TLS)
EXPOSE 5223
# XMPP server-to-server
EXPOSE 5269
# XMPP BOSH/WebSocket
EXPOSE 5280
# XMPP secure BOSH/WebSocket
EXPOSE 5443
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD ejabberdctl status || exit 1
ENTRYPOINT ["/entrypoint.sh"]
CMD ["foreground"]

Creating ejabberd Configuration

Create config/ejabberd.yml:

###
### ejabberd configuration file
###
# Logging
loglevel: info
log_rotate_size: 10485760
log_rotate_count: 5
# Virtual hosts
hosts:
- ${XMPP_DOMAIN:-localhost}
# Certificates
certfiles:
- /home/ejabberd/certs/*.pem
# Listening ports
listen:
-
port: 5222
ip: "::"
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
starttls_required: true
-
port: 5223
ip: "::"
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
tls: true
-
port: 5269
ip: "::"
module: ejabberd_s2s_in
max_stanza_size: 524288
-
port: 5443
ip: "::"
module: ejabberd_http
tls: true
request_handlers:
/admin: ejabberd_web_admin
/api: mod_http_api
/bosh: mod_bosh
/captcha: ejabberd_captcha
/upload: mod_http_upload
/ws: ejabberd_http_ws
-
port: 5280
ip: "::"
module: ejabberd_http
request_handlers:
/admin: ejabberd_web_admin
/.well-known/acme-challenge: ejabberd_acme
# S2S configuration
s2s_use_starttls: required
# Authentication
auth_method: internal
auth_password_format: scram
# ACLs
acl:
admin:
user:
- admin@${XMPP_DOMAIN:-localhost}
local:
user_regexp: ""
loopback:
ip:
- 127.0.0.0/8
- ::1/128
# Access rules
access_rules:
local:
allow: local
c2s:
deny: blocked
allow: all
announce:
allow: admin
configure:
allow: admin
muc_create:
allow: local
pubsub_createnode:
allow: local
trusted_network:
allow: loopback
# API permissions
api_permissions:
"admin access":
who:
access:
allow:
- acl: admin
what:
- "*"
- "!stop"
- "!start"
# Shaper rules
shaper:
normal:
rate: 3000
burst_size: 20000
fast: 100000
shaper_rules:
max_user_sessions: 10
max_user_offline_messages:
5000: admin
100: all
c2s_shaper:
none: admin
normal: all
s2s_shaper: fast
# Modules
modules:
mod_adhoc: {}
mod_admin_extra: {}
mod_announce:
access: announce
mod_avatar: {}
mod_blocking: {}
mod_bosh: {}
mod_caps: {}
mod_carbons: {}
mod_client_state: {}
mod_configure: {}
mod_disco: {}
mod_fail2ban: {}
mod_http_api: {}
mod_http_upload:
put_url: https://@HOST@:5443/upload
custom_headers:
"Access-Control-Allow-Origin": "*"
"Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
"Access-Control-Allow-Headers": "Content-Type"
mod_last: {}
mod_mam:
default: always
request_activates_archiving: true
mod_muc:
access:
- allow
access_admin:
- allow: admin
access_create: muc_create
access_persistent: muc_create
default_room_options:
mam: true
persistent: true
public: true
public_list: true
mod_muc_admin: {}
mod_offline:
access_max_user_messages: max_user_offline_messages
mod_ping: {}
mod_privacy: {}
mod_private: {}
mod_proxy65:
access: local
max_connections: 5
mod_pubsub:
access_createnode: pubsub_createnode
plugins:
- flat
- pep
force_node_config:
storage:bookmarks:
access_model: whitelist
mod_push: {}
mod_push_keepalive: {}
mod_register:
welcome_message:
subject: Welcome!
body: |-
Welcome to the XMPP server!
ip_access: trusted_network
access: register
mod_roster:
versioning: true
mod_s2s_dialback: {}
mod_shared_roster: {}
mod_stream_mgmt:
resend_on_timeout: if_offline
mod_vcard: {}
mod_vcard_xupdate: {}
mod_version:
show_os: false

Creating Entrypoint Script

Create scripts/entrypoint.sh:

#!/bin/bash
set -e
# Substitute environment variables in config
envsubst < /home/ejabberd/conf/ejabberd.yml > /home/ejabberd/conf/ejabberd.yml.tmp
mv /home/ejabberd/conf/ejabberd.yml.tmp /home/ejabberd/conf/ejabberd.yml
# Start ejabberd
exec /home/ejabberd/bin/ejabberdctl "$@"

Creating the .dockerignore File

Create a .dockerignore file:

.git
.github
*.md
LICENSE
.gitignore
.DS_Store

Deploying ejabberd on Klutch.sh

Follow these steps to deploy your ejabberd server:

    Configure DNS Records

    Set up DNS records for XMPP:

    Record TypeNameValue
    AxmppYour server IP
    SRV_xmpp-client._tcp5 0 5222 xmpp.example.com
    SRV_xmpp-server._tcp5 0 5269 xmpp.example.com

    Prepare TLS Certificates

    Obtain TLS certificates for your domain. You can use Let’s Encrypt or commercial certificates.

    Push Your Repository to GitHub

    Initialize and push your configuration:

    Terminal window
    git init
    git add .
    git commit -m "Initial ejabberd configuration"
    git remote add origin https://github.com/yourusername/ejabberd-deploy.git
    git push -u origin main

    Create a New Project on Klutch.sh

    Navigate to the Klutch.sh dashboard and create a new project for your messaging platform.

    Create a New App

    Create a new app within your project and connect your GitHub repository.

    Configure Traffic Settings

    ejabberd requires multiple ports:

    • Port 5222: Client connections (STARTTLS)
    • Port 5223: Client connections (Direct TLS)
    • Port 5269: Server-to-server federation
    • Port 5443: HTTPS (admin, BOSH, WebSocket)

    Set Environment Variables

    Configure the following environment variables:

    VariableValue
    XMPP_DOMAINexample.com
    EJABBERD_ADMINSadmin@example.com

    Attach Persistent Volumes

    Add persistent volumes for ejabberd:

    Mount PathRecommended SizePurpose
    /home/ejabberd/database50 GBMnesia database and message archive
    /home/ejabberd/upload50 GBFile uploads
    /home/ejabberd/certs100 MBTLS certificates

    Deploy Your Application

    Click Deploy to build and start ejabberd.

    Create Admin Account

    After deployment, create the admin account:

    Terminal window
    ejabberdctl register admin example.com your-password

    Access Web Admin

    Access the web admin at https://xmpp.example.com:5443/admin/

Managing Users

Creating Users

Create user accounts via command line:

Terminal window
ejabberdctl register username example.com password

Or via the web admin interface.

User Registration

Configure in-band registration for self-service:

mod_register:
access: register
welcome_message:
subject: Welcome!
body: Welcome to our XMPP server!

Control who can register:

access_rules:
register:
allow: all # Or restrict to specific IPs

Managing Accounts

Common account operations:

Terminal window
# Change password
ejabberdctl change_password user example.com newpassword
# Delete account
ejabberdctl unregister user example.com
# List registered users
ejabberdctl registered_users example.com

Multi-User Chat (MUC)

Creating Chat Rooms

Users create rooms by joining a new room address, or admins can create persistent rooms:

Terminal window
ejabberdctl create_room roomname conference.example.com example.com

Room Configuration

Configure default room options:

mod_muc:
default_room_options:
persistent: true
public: true
members_only: false
allow_private_messages: true
mam: true

Room Administration

Manage rooms via ejabberdctl:

Terminal window
# List rooms
ejabberdctl muc_online_rooms conference.example.com
# Destroy room
ejabberdctl destroy_room roomname conference.example.com
# Get room affiliations
ejabberdctl get_room_affiliations roomname conference.example.com

Message Archive Management (MAM)

Enabling MAM

MAM stores messages server-side for offline access:

mod_mam:
default: always
request_activates_archiving: true
db_type: sql # Or mnesia
cache_size: 1000
cache_life_time: 3600

Archive Retention

Configure message retention:

mod_mam:
clear_archive_on_room_destroy: true
default: always

Querying Archives

Users query archives using MAM XEP-0313 from compatible clients.

Federation

Server-to-Server

Enable federation with other XMPP servers:

s2s_use_starttls: required
s2s_access: all

Restricting Federation

Limit federation to specific domains:

s2s_access:
allow:
- domain: partner.com
- domain: trusted.org
deny: all

Push Notifications

Configuring Push

Enable push notifications for mobile apps:

mod_push: {}
mod_push_keepalive: {}

iOS/Android Support

Push requires app-specific configuration:

  1. Configure APNs for iOS
  2. Configure FCM for Android
  3. Set up push gateway service

Web Clients

BOSH

Enable BOSH for web client support:

listen:
-
port: 5280
module: ejabberd_http
request_handlers:
/bosh: mod_bosh
mod_bosh: {}

WebSocket

Enable WebSocket for modern web clients:

listen:
-
port: 5280
module: ejabberd_http
request_handlers:
/ws: ejabberd_http_ws

Production Best Practices

Performance Optimization

  • Mnesia Tuning: Adjust Mnesia settings for large deployments
  • Connection Limits: Set appropriate max_stanza_size
  • Shaper Rules: Configure traffic shaping for fairness

Security Recommendations

  • TLS Required: Enforce TLS for all connections
  • Strong Authentication: Use SCRAM-SHA-256
  • Rate Limiting: Enable mod_fail2ban
  • Regular Updates: Keep ejabberd updated

High Availability

For critical deployments:

  1. Set up ejabberd clustering
  2. Configure external database (PostgreSQL)
  3. Use load balancer for client connections

Backup Strategy

Regular backups should include:

  1. Mnesia database directory
  2. Configuration files
  3. TLS certificates
  4. Upload directory

Troubleshooting Common Issues

Connection Failures

Symptoms: Clients cannot connect.

Solutions:

  • Verify DNS SRV records
  • Check TLS certificate validity
  • Ensure ports are exposed
  • Review ejabberd logs

Authentication Issues

Symptoms: Users cannot log in.

Solutions:

  • Verify account exists
  • Check password format
  • Ensure auth module is configured
  • Review auth logs

Federation Not Working

Symptoms: Cannot communicate with other servers.

Solutions:

  • Verify DNS configuration
  • Check S2S port accessibility
  • Confirm TLS certificates
  • Review s2s logs

Message Delivery Issues

Symptoms: Messages not arriving.

Solutions:

  • Check offline message limits
  • Verify MAM configuration
  • Review message routing
  • Check recipient status

Additional Resources

Conclusion

Deploying ejabberd on Klutch.sh gives you a battle-tested, scalable XMPP server for real-time communication. The combination of ejabberd’s Erlang-based reliability and Klutch.sh’s container management means you can run enterprise-grade messaging without complex infrastructure.

With support for federation, multi-user chat, message archiving, and modern features like push notifications and WebSocket, ejabberd handles everything from small team chat to large-scale communication platforms. Whether you’re building internal messaging for your organization or creating a public chat service, ejabberd on Klutch.sh provides the foundation for reliable, secure real-time communication.