You are here

Running Jabber/XMPP client Kaiwa on FreeBSD

Not so frequently asked questions and stuff: 

The FreeBSD logo Image
Let's install Kaiwa on FreeBSD.

Installing Kaiwa

Install nodejs:

# make -C /usr/ports/www/node install clean

Install npm:

# make -C /usr/ports/www/npm install clean

Create a directory to host the code and go there:

# mkdir /usr/local/www/kaiwa
# cd /usr/local/www/kaiwa

Clone the repository:

# git clone .

If you don't have git, you can download the zip file and extract it.

Install the dependencies:

# npm install

Configuring ejabberd

My Jabber/XMPP server is ejabberd.

Here's the relevant part: we must ensure there's a path wired to handler ejabberd_http_ws in /usr/local/etc/ejabberd/ejabberd.yml.

  ## To handle XML-RPC requests that provide admin credentials:
  ## -
  ##   port: 4560
  ##   module: ejabberd_xmlrpc
    port: 5280
    module: ejabberd_http
    ## request_handlers:
    ##   "/pub/archive": mod_http_fileserver
      "/websocket": ejabberd_http_ws
    web_admin: true
    http_poll: true
    http_bind: true
    ## register: true
    captcha: true

Make sure port 5280 is open in your firewall.

Configure Kaiwa

Copy the example config file:

# cp dev_config.example.json dev_config.json

Here's what I put in there:

    "isDev": true,
    "http": {
        "host": "localhost",
        "port": 8000
    "session": {
        "secret": "wSPwBucqnCY4JHEENMY6NM4UsfycNz"
    "server": {
        "name": "Example",
        "domain": "",
        "wss": "ws://",
        "muc": "",
        "startup": "groupchat/",
        "admin": "admin"

Running Kaiwa

Create a user to run the service:

# pw useradd kaiwa

Allow the user to feel at home in the code directory:

# chown -R kaiwa:kaiwa /usr/local/www/kaiwa

You can check if everything is working by running the service manually:

# sudo -u kaiwa node server

If everything is fine, install forever to make sure the service is always running:

# npm install forever -g

Create the logs, give them to the right user and configure newsyslog to rotate them:

# touch /var/log/kaiwa.log
# touch /var/log/kaiwa-error.log
# touch /var/log/kaiwa-forever.log
# chown kaiwa:kaiwa /var/log/kaiwa*

echo "/var/log/kaiwa.log kaiwa:kaiwa 640 3 100 * JC /var/run/" >> /etc/newsyslog.con
echo "/var/log/kaiwa-error.log kaiwa:kaiwa 640 3 100 * JC /var/run/" >> /etc/newsyslog.con
echo "/var/log/kaiwa-forever.log kaiwa:kaiwa 640 3 100 * JC /var/run/" >> /etc/newsyslog.con

For thing for the pid file location:

# mkdir /var/run/kaiwa
# chown kaiwa:kaiwa /var/run/kaiwa

Create a rc script in /usr/local/etc/rc.d/kaiwa and make sure it's executable.


# In addition to kaiwa_enable, the following rc variables should be defined:

# kaiwa_msg      The name of your program, printed at start. Defaults to "kaiwa".
# kaiwa_dir      The directory where your node files live. Must be defined.
# kaiwa_logdir   The directory for logfiles. Defaults to ${kaiwa_dir}/logs.
# kaiwa_user     Sudoed before running. Defaults to "kaiwa".
# kaiwa_app      Application main script. Defaults to "server.js" (relative
#               to kaiwa_user's home
# kaiwa_forever  forever binary file path. Defaults to "/usr/local/bin/forever".
# kaiwa_local_forever    use local forever binary
#               (ie. kaiwa_user's home/kaiwa_modules/.bin/forever)
# kaiwa_forever_log      forever log file. Defaults to /var/log/forever.log.

# PROVIDE: kaiwa
# KEYWORD: shutdown

. /etc/rc.subr



# kaiwa executable

# forever needs a path for each command

# get rc vars
load_rc_config $name
: ${kaiwa_enable:="no"}
: ${kaiwa_msg:="kaiwa"}
: ${kaiwa_logdir:="/var/log"}
: ${kaiwa_user:="kaiwa"}
: ${kaiwa_app:="server.js"}
: ${kaiwa_forever:="/usr/local/bin/forever"}
: ${kaiwa_local_forever:="no"}
: ${kaiwa_forever_log:="/var/log/kaiwa-forever.log"}

case ${kaiwa_local_forever} in

# make sure we're pointing to the right place

# any other checks go here
    echo "$kaiwa_msg starting"

    ${kaiwa_forever} start -a -l ${kaiwa_forever_log} -o ${kaiwa_logdir}/kaiwa.log \
        -e ${kaiwa_logdir}/kaiwa-error.log --minUpTime 3000 --pidFile ${pidfile} \
        --workingDir ${kaiwa_dir} ${kaiwa_dir}/${kaiwa_app}

    # kill kaiwa nicely -- node should catch this signal gracefully
    ${kaiwa_forever} stop --killSignal SIGTERM `cat ${pidfile}`

run_rc_command "$1"

Enable the daemon in /etc/rc.conf:


Start Kaiwa and enjoy

Start the service:

# service kaiwa start

Check that the daemon is listening:

# sockstat -4l | grep kaiwa
kaiwa node       54296 11 tcp4       *:*