Kazoo v4 Single Server Install Guide


Kazoo is a highly scalable API based VoIP telephony platform.  This guide shows how to install Kazoo v4 on one CentOS v7 server.  It can be used in conjunction with our Kazoo multiple server guide for more than one server.


Use HAProxy and external IP for multi-server compatibility. 


CentOS v7 minimal ISO
RabbitMQ message broker v3
BigCouch NoSQL database v0.4
HAProxy http load balancer v1.5
FreeSWITCH media server v1.6
Kamailio SIP server v4
Kazoo erlang stack v4


FQDN check

It is necessary for  hostname and hostname -f to both return the fully qualified domain name.  If not the same or not a FQDN then edit /etc/hostname and reboot.  
Local FQDNs are ok for a single server install.
# For example:
If using a virtualization platform that overwrites /etc/hostname incorrectly on reboot, set the file to prevent overwriting.
​chattr +i /etc/hostname 

Disable Selinux

Check status.


If not disabled, do the following and reboot.

sed -i 's/\(^SELINUX=\).*/\SELINUX=disabled/' /etc/selinux/config

Disable firewall

It is sometimes helpful to disable the firewall during install.

systemctl disable firewalld
systemctl disable iptables
systemctl stop firewalld
systemctl stop iptables


Kazoo assumes UTC system time.  From there it is converted to the individual account timezones. Having system time set to something else will cause those conversions to be incorrect. 

yum install ntp
systemctl enable ntpd
systemctl start ntpd
timedatectl set-timezone UTC



yum -y install wget gdb yum-utils epel-release

Kazoo, Kamailio, and Freeswitch Repositories

Check for latest released version and modify 2600hz-release-x.x-x as necessary.

cd /usr/src
wget --no-check-certificate \
rpm -Uvh 2600hz-release-4.0-2.el7.centos.noarch.rpm

yum-config-manager --disable 2600hz-experimental
yum-config-manager --enable 2600hz-stable


This is how the kazoo applications talk to each other.

yum install kazoo-rabbitmq

systemctl enable kazoo-rabbitmq
systemctl restart kazoo-rabbitmq
systemctl status kazoo-rabbitmq


# Check that RabbitMQ is listening
ss -lpn | grep "5672"

# Check API
curl -i -u guest:guest http://localhost:15672/api/overview
curl -i -u guest:guest http://localhost:15672/api/aliveness-test/%2F

# Check status
kazoo-rabbitmq status

Config file is located at /etc/kazoo/rabbitmq


This will eventually be replaced by CouchDB v2.  It is possible to install CouchDB from source and use that instead.  That is beyond the scope if this guide. 

yum install kazoo-bigcouch

systemctl enable kazoo-bigcouch
systemctl restart kazoo-bigcouch
systemctl status kazoo-bigcouch


# Check that BigCouch is listening
ss -ln | egrep "5984|5986"

# Check frontend API
curl localhost:5984

# Check admin API
curl localhost:5986
Config files are located at/etc/kazoo/bigcouch


yum install kazoo-haproxy

systemctl enable kazoo-haproxy
systemctl restart kazoo-haproxy
systemctl status kazoo-haproxy


# Check BigCouch frontend API via HAproxy
curl localhost:15984

# Check BigCouch admin API via HAproxy
curl localhost:15986

You can now use port 5984 or 15984 locally, as long as HAproxy is running.

Config file is located at /etc/kazoo/haproxy


yum install kazoo-freeswitch

systemctl enable kazoo-freeswitch
systemctl restart kazoo-freeswitch
systemctl status kazoo-freeswitch
# Check FreeSWITCH status
fs_cli -x status

Config files are located at /etc/kazoo/freeswitch


yum install kazoo-kamailio
​# Save a copy of config file for future reference
cp /etc/kazoo/kamailio/local.cfg /etc/kazoo/kamailio/local.cfg.orig
# Get serverIP x.x.x.x.
hostname -I

# Create serverFQDN variable

## Replace x.x.x.x with ServerIP
# This only works the first time.  The file needs to be updated manually after that

sed -i "s/127\.0\.0\.1/x.x.x.x/g" /etc/kazoo/kamailio/local.cfg

 Add FreeSWITCH IP to the dispatcher list.  Replace x.x.x.x with serverIP
echo ":1:sip\:x.x.x.x\:11000:0:0::aio-fs" >> /etc/kazoo/kamailio/dbtext/dispatcher

## Update the serverFQDN
# This only works the first time.  The file needs to be updated manually afterwards.

sed -i "s/kamailio\.2600hz\.com/$serverFQDN/g" /etc/kazoo/kamailio/local.cfg
systemctl enable kazoo-kamailio
systemctl restart kazoo-kamailio
systemctl status kazoo-kamailio

# Fix a legacy issue with Kamailio RPM
/usr/sbin/chkconfig kamailio off

Useful commands

​# Check that Kamailio is listening
ss -ln | egrep "5060|7000"

# Reload dispatcher
kamctl fifo ds_reload

# Check dispatcher status
kazoo-kamailio status

# Check kamailio stats
kamctl stats

Config files are located at /etc/kazoo/kamailio

Kazoo Apps

yum install kazoo-applications kazoo-application-*

systemctl enable kazoo-applications
systemctl restart kazoo-applications
systemctl status kazoo-applications

Check DB creation

# Check that some databases have been created
# It may take several minutes before all of them are added

curl localhost:5984/_all_dbs

# Check the total number of dbs (lower left)
# If not > 20 wait a few minutes and check again before proceeding further

curl localhost:5984/_all_dbs | python -mjson.tool | wc -l

Install sound files

# Check that the system_media db has been created
curl localhost:5984/system_media

# Import english sound files into database
sup kazoo_media_maintenance import_prompts /opt/kazoo/sounds/en/us/

# For alternative languages, install the relevant RPMs (core & freeswitch) and modify above command.
yum search kazoo-sounds

Create master account

# Check that the accounts db has been created
curl localhost:5984/accounts

# Create the master account and superadmin user, substituting in your own values  
# ACCOUNTREALM is used internally to identify individual accounts
# It needs to be internally unique and in FQDN format but does not need to be resolvable
# IF ACCOUNTREALM is DNS resolvable, devices can access account by using realm instead of IP + realm. 

sup crossbar_maintenance create_account ACCOUNTNAME ACCOUNTREALM ADMINUSER ADMINPASS

# So for example
sup crossbar_maintenance create_account master master.local superadmin somepassword 

To understand the account hierarchy refer to this link.    In case that link does not work for some reason, this basic hierarchy diagram might be of some help.

To understand how account credentials are used refer to this link.  In case that link does not work, this account login diagram and this device lookup diagram might help.


Erlang call manager.  Abstracts and clusters Freeswitch.

systemctl enable kazoo-ecallmgr
systemctl restart kazoo-ecallmgr
systemctl status kazoo-ecallmgr

# Start ecallmgr app
sup kapps_controller start_app ecallmgr

# Add ecallmgr app to the database so that it automatically starts on boot
# Replace x.x.x.x with the ServerIP in your web browser


# Add "ecallmgr" to "kapps" list at above link
# Check green check mark on right to update
# Select "Save Document" at top  

Add Freeswitch and Kamailio

# Create serverFQDN variable

sup ecallmgr_maintenance add_fs_node freeswitch@$serverFQDN

# Add Kamailio to the SBC ACL so that Freeswitch allows the traffic
# Replace x.x.x.x with serverIP

sup ecallmgr_maintenance allow_sbc kamailio1 x.x.x.x


# Check FreeSWITCH connection
fs_cli -x "erlang status"

# Check the sip stack.  Should show at least one profile
fs_cli -x 'sofia status'

# Check SBC ACL
sup ecallmgr_maintenance sbc_acls

# Check app status
# You should see 3 nodes listed.  Apps, Kamailio, and Ecallmgr.
# Freeswitch media server should be listed under apps and ecallmgr nodes

kazoo-applications status

# Check that Kamailio sees FreeSWITCH
# If flags=IP, there is a problem somewhere

kazoo-kamailio status


This is the name of the REST API server.

# Check that crossbar is accessible
# 401 invalid credentials error is the expected response

curl http://x.x.x.x:8000/v2
Detailed documentation on the REST API is available at the following link.

Monster UI

An end user interface that interacts with the REST API.

yum install monster-ui* httpd

systemctl enable httpd
systemctl restart httpd
systemctl status httpd

Configure and initialize

# Get serverIP x.x.x.x
hostname -I

# Replace x.x.x.x with serverIP
# This only works the first time  
# The IP needs to be changed manually after that

sed -i "s/localhost/x.x.x.x/" /var/www/html/monster-ui/js/config.js

# Initialize Monster Apps
# Replace x.x.x.x with ServerIP

sup crossbar_maintenance init_apps /var/www/html/monster-ui/apps http://x.x.x.x:8000/v2

Change web server root directory

#Create serverFQDN variable

# Create the virtual host

echo "<VirtualHost *:80>
  DocumentRoot \"/var/www/html/monster-ui\"
  ServerName $serverFQDN
" > /etc/httpd/conf.d/monster-ui.conf

# Reload web server for changes to take effect
systemctl reload httpd
Browse to Monster UI and login.


SUP commands list

These are used to communicate with Kazoo, at a very low level, via Erlang.

# Build list of SUP commands

/opt/kazoo/lib/sup*/priv/build-autocomplete.escript \
/etc/bash_completion.d/sup.bash /opt/kazoo > /usr/doc/sup_commands

# View list

cat /usr/doc/sup_commands


The database structures.  Can help determine configurable properties.

SIP Trunks

SIP trunks can be global or local.  Global trunks are added to the offnet database and are accessible by all accounts.  Local trunks are added to each account.

Monster UI does not currently have a public app for managing SIP trunks.  However, it is still possible to use the discontinued Kazoo UI in parallel for adding local trunks. 

For adding global SIP trunks, the easiest way is via the API.  There are tools such as postman and apiexplorer that help simplify it further.  There is a swagger.json file that can be imported into postman to add the API commands.  How to configure all that and do things directly via API is beyond the scope of this document.

Here is a reference document which explains the basics using command line.

Some additional info.

Reference install guide