Skip to content

Instantly share code, notes, and snippets.

@bkw
Created January 27, 2013 16:28
Show Gist options
  • Save bkw/4649106 to your computer and use it in GitHub Desktop.
Save bkw/4649106 to your computer and use it in GitHub Desktop.
Unsuck Macports CouchDB With Node.JS

Unsucking Macports CouchDB with node.js

Why?

The macports couchdb port has problems. The hip thing to do would probably be switching over to homebrew, but I dislike brew for a couple of reasons, which are beyond the scope of this writeup. Also, building from source failed for me with some strange problem in the makefile, that I'll hunt down later.

So, what's wrong with it?

  • couchdb's javascript viewserver couchjs links against libjs.dylib, which is supplied by the spidermonkey port. That port is ancient, but cannot be easily upgraded because of, well... mongodb. That means: no ES5-goodness for the rest of us. :-(
  • The launchd configuration sets DYLD_LIBRARY_PATH, which is carried over to the invocation of the couchjs server, which creates problems if you try to exchange it for something else (see below).

How to fix it

  • Either: install your own version of spidermonkey and make couchdb link couchjs against it (described in the CouchDB Wiki, I did not try that)
  • Or: get the nodejs replacement for couchjs by iriscouch and throw out the DYLD_LIBRARY_PATH setting.

Install node.js couchjs

This assumes you have a working installation of a current node.js.

Note: At the time of this writing, the latest released version of couchjs up on npmjs.org was 0.1.0, which has problems with very large views. That's why I currently recommend installing it from the github master. The next released version will not have this problem, since the fix already is comitted.

$ git clone https://github.com/iriscouch/couchjs.git
$ cd couchjs
$ sudo npm install -g

As soon as @jhs pushed the next version to npm, you can simply do:

$ sudo npm install -g couchjs

Now you should have a symlink /usr/local/bin/couchjs (depending on the path prefix your npm uses) pointing to cli.js of your couchjs npm installation.

Important: If your npm modules get installed with prefix /opt/local, this may have either failed or overridden the couchjs binary by couchdb already. This also means it will be overwritten every time you upgrade couchdb from macports. That's why I don't use that path directly (see below).

Remove DYLD_LIBRARY_PATH from launchd script

From what I could dig up, the only reason DYLD_LIBRARY_PATH is set at all is to force the use of the macports spidermonkey port, which we don't want. Even worse: setting it breaks node.js:

$ DYLD_LIBRARY_PATH=/opt/local/lib node
dyld: Symbol not found: _iconv
  Referenced from: /usr/lib/libcups.2.dylib
  Expected in: /opt/local/lib/libiconv.2.dylib
 in /usr/lib/libcups.2.dylib
[1]    17801 trace trap  DYLD_LIBRARY_PATH=/opt/local/lib node

Since the environment is inherited by child processes, using the node based couchjs server would break as well. Time to get rid of that setting:

$ sudo sed -i '.orig' 's/.*DYLD_LIBRARY_PATH.*//' \
  /opt/local/Library/LaunchDaemons/org.apache.couchdb.plist

Enable the node based couchjs view server by adding it to local.ini (alter your paths for node and node_modules according to your setup):

$ ( NODE=/usr/local/bin/node; \
    COUCHJS=/usr/local/lib/node_modules/couchjs/cli.js; \
    JSPATH=/opt/local/share/couchdb/server; \
    echo "[query_servers]"; \
    echo "javascript = $NODE $COUCHJS $JSPATH/main.js"; \
    echo "coffeescript = $NODE $COUCHJS $JSPATH/main-coffee.js"; \
  ) | sudo tee -a /opt/local/etc/couchdb/local.ini

The reason I give an explicit path to node and the cli script (as opposed to just pointing to the just installed couchjs symlink) is to avoid collisions with couchjs by the couchdb distribution.

Restart couchdb

$ sudo launchctl unload /Library/LaunchDaemons/org.apache.couchdb.plist
$ sudo launchctl load -w /Library/LaunchDaemons/org.apache.couchdb.plist

Try it out

Fire up futon and run a temporary view using ES5 features:

function(doc) {
   emit(null, Object.keys(doc));
}

If that succeeds, you are running the right view server and can start using nodejs awesomeness from within your couchdb javascript code.

@jhs
Copy link

jhs commented Jan 27, 2013

Awesome!

You could also use the /_config API to change those config values. (It does the same thing as editing the file.) CouchDB will work just fine with busted query server configs. So you could start it first and then correct those settings over HTTP. Something like this:

curl -X PUT http://localhost:5984/_config/query_servers/javascript -d "\"$NODE $COUCHJS $JSPATH/main.js\""

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment