You are here

Running Jabber/XMPP client Kaiwa on FreeBSD

Not so frequently asked questions and stuff: 

The FreeBSD logoImage
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