hipache

I’ve been trying out using hipache as a routing web proxy. It uses redis as a configuration store of sorts, so you can add webroutes (not sure what to call them…vhost routes?) without having to reload or restart hipache.

Running it on Ubuntu 12.04 was fairly straight forward, other than I had to install a much newer version of nodejs and npm than what comes with the distro by default.

Install new npm, nodejs, and hipache

So first, get a recent version of nodejs.

# get a newer version of node
root# grep DESC /etc/lsb-release 
DISTRIB_DESCRIPTION="Ubuntu 12.04.4 LTS"
root# sudo apt-get update
root# sudo apt-get install -y python-software-properties python g++ make
root# sudo add-apt-repository ppa:chris-lea/node.js
root# sudo apt-get update
root# sudo apt-get install nodejs
root# node --version
v0.10.26

Next get a new npm…using npm.

root# apt-get install npm
# now update npm using npm
root# npm install npm -g --ca=null
root# npm config set ca=""
root# npm --version
1.3.26

Now install hipache.

root# npm install hipache -g

Install redis

hipache uses redis as a data store for webroutes.

I installed version 2.8.7 stable from source.

root# wget http://download.redis.io/releases/redis-2.8.7.tar.gz
root# tar zxf redis-2.8.7.tar.gz
root# cd redis-2.8.7
root# make
root# make install
root# cd utils
# Setup redis init stuff
root# ./install_server.sh

At this point I had to edit the /etc/init.d/redis_6379 file because it had a bunch of “\n\n” newlines that weren’t converted for some reason. I’ll have to check into that later on.

The head of that file should look like this.

root# head redis_6379 
#/bin/sh
#Configurations injected by install_server below....
EXEC=/usr/local/bin/redis-server
CLIEXEC=/usr/local/bin/redis-cli
PIDFILE=/var/run/redis_6379.pid
CONF="/etc/redis/6379.conf"
REDISPORT="6379"
###############

case "$1" in

I configured redis to only to listen on localhost.

root# grep bind 6379.conf 
# interfaces using the "bind" configuration directive, followed by one or
# bind 192.168.1.100 10.0.0.1
bind 127.0.0.1

Now we can start it.

Start redis

Use service to start redis.

root# service redis_6379 start

It’s now listening on 6379.

root# netstat -ant  |grep 6379  | grep LISTEN
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN    

Start hipache

Hipache provides an upstart script.

# hipache - distributed HTTP and websocket proxy

start on runlevel [2345]
stop on runlevel [06]

respawn
respawn limit 15 5

script
  hipache --config /etc/hipache.json
end script

I placed that in /etc/init/hipache.conf

root# ls /etc/init/hipache.conf 
/etc/init/hipache.conf

Finally we need a hipache config file.

root# cat /etc/hipache.json 
{
    "server": {
        "accessLog": "/var/log/hipache_access.log",
        "port": 80,
        "workers": 5,
        "maxSockets": 100,
        "deadBackendTTL": 30,
        "address": ["127.0.0.1"],
        "address6": ["::1"]
    },
    "redisHost": "127.0.0.1",
    "redisPort": 6379,
    "redisDatabase": 0,

}

Obviously this is a test config with no password, but it is only listening on localhost.

We can start hipache.

root# service hipache start

Configure vhosts

vhosts for hiapche to proxy are entered into redis.

Here’s an example taken from the README:

$ redis-cli rpush frontend:www.dotcloud.com mywebsite
(integer) 1
$ redis-cli rpush frontend:www.dotcloud.com http://192.168.0.42:80
(integer) 2
$ redis-cli rpush frontend:www.dotcloud.com http://192.168.0.43:80
(integer) 3
$ redis-cli lrange frontend:www.dotcloud.com 0 -1
1) "mywebsite"
2) "http://192.168.0.42:80"
3) "http://192.168.0.43:80"

Now accessing a hostname/URL that is associated with the IP hipache is listening on will redirect to the backend servers set in redis, assuming the vhost dns name is configured properly, and we can keep adding them and reconfiguring without taking down hipache.

There isn’t a ton of documentation on using hipache, so I’m betting that I’ll eventually run into a wall with it, but for now it’s a pretty interesting project that not only gets me introduced to nodejs but also redis.

Also I should setup an ansible role to do this. Not too happy about the packaging here either, upstart scripts all over the place.