Running Jabber/XMPP client Kaiwa on FreeBSD


Yes, people still use Jabber

January 2017.
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 https://github.com/digicoop/kaiwa.git .

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
request_handlers:
"/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": "example.com",
"wss": "ws://example.com:5280/websocket/",
"muc": "",
"startup": "groupchat/example%40chat.example.com",
"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/kaiwa.pid" >> /etc/newsyslog.con
echo "/var/log/kaiwa-error.log kaiwa:kaiwa 640 3 100 * JC /var/run/kaiwa.pid" >> /etc/newsyslog.con
echo "/var/log/kaiwa-forever.log kaiwa:kaiwa 640 3 100 * JC /var/run/kaiwa.pid" >> /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.

#!/bin/sh

# 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
# REQUIRE: LOGIN
# KEYWORD: shutdown

. /etc/rc.subr

name="kaiwa"
rcvar="${name}_enable"

start_precmd="${name}_prestart"
start_cmd="${name}_start"
stop_cmd="${name}_stop"

# kaiwa executable
command="/usr/local/bin/forever"
pidfile="/var/run/${name}/${name}.pid"

# forever needs a path for each command
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin

# 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
[Yy][Ee][Ss])
kaiwa_forever="/usr/local/www/kaiwa/node_modules/.bin/forever"
;;
*)
;;
esac


# make sure we're pointing to the right place
required_dirs="${kaiwa_dir}"
required_files="${kaiwa_dir}/${kaiwa_app}"

# any other checks go here
kaiwa_prestart()
{
echo "$kaiwa_msg starting"
}

kaiwa_start()
{
${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}
}

kaiwa_stop()
{
# 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:

kaiwa_enable="YES"
kaiwa_dir="/usr/local/www/kaiwa"

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 10.2.0.141:8000 *:*

Image