Throw your Node.JS apps in /var/webapps/vhosts and let 'er rip!
Pull request Compare This branch is 7 commits behind coolaj86:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


You can host multiple applications for different domains (aka vhosts) using a single node instance.

The advantage is that you can host a lot of applications on a single VPS (or your local development machine) and use only the memory required for a single node instance, reducing overhead and increasing performance.

Although the applications will be sandboxed from throw error, a memory leak or process.exit() in one application will affect all applications.

Now with github Post-Receive Hooks!


Let's say you've got an Ubuntu VPS where you want to host your very own copy of foobar3000.

Install vhoster

I like to install vhoster to /var/webapps and have a link in my local directory.

sudo git clone git:// /var/webapps
sudo chown -R `whoami`:`whoami` /var/webapps
ln -s /var/webapps ~/webapps
cd ~/webapps
npm install


Copy the config.defaults.js and season to taste (read on for more options).

cp -a config.default.js config.js

Install applications

mkdir vhosts
git clone ~/webapps/vhosts/
cd ~/webapps/vhosts/
npm install

Note: Any applications with parse errors or that otherwise fail to load are skipped at load time.

Set aliases

The folder name of each vhost app should be the primary (production) domain name.

For development boxes and local setups you can have additional aliases in aliases.js:

vim ~/webapps/vhosts/

Should look something like: (function () { "use strict";

  module.exports = [
    , "foobar3000.local"
    , "helloworld3000.local"

For local testing you can edit /etc/hosts and add things like

  • foobar3000.local - for local testing

Note: www prefixes are automatically removed and redirected.

Note: vhosts are handled intelligently and with forgiveness (see below for an example).

Upstart in Ubuntu

vim webapps.conf
# change path from `/var/webapps` to wherever you choose
sudo cp webapps.conf /etc/init/

GitHub Post-Recieve URLs

For your development boxes you can have your applications reload on each commit. Amazing!

  1. Set config.js:githubAuth to a nice long password that will only be used by github
  2. Check that you agree with ~/webapps/ (fetch, pull, submodule update, npm install)
    • you can place per-vhost scripts as ~/webapps/vhosts/
    • custom scripts run in place of the provided script for that vhost only
  3. Go to -> your application -> admin -> Service Hooks -> Post-Receive URLs
  4. Add a URL in the semblance of
    • /github-hook is mandatory, a hard-coded part of the github-hook module
    • username:password is whatever you set in config.js:githubAuth and not your github account
    • should be replaced by the name of any of you vhosts

If config.js:githubAuth exists, then any request with the URL /github-hook with valid HTTP Basic Auth will run ~/webapps/ and exit node upon completion. If you're using upstart or something similar, the respawn option will cause your site to reload.

Note: github-hook is loaded before any other module, so any vhost will work as well as any other.

Note: Github hooks are only sent once. If your vhoster is down because just 3 seconds before you already pushed, probably only the first commit will take.

How the vhosts load

If your directory structure looks like this:

  • ./vhosts/
  • ./vhosts/
  • ./vhosts/
  • ./vhosts/

And you have a few aliases.js that look like this:

  • ./vhosts/

      module.exports = [ "foobar3000.local", "helloworld3000.local" ];

All vhosts will be ordered longest to shortest like so:

  • *
  • *
  • *.foobar3000.local
  • foobar3000.local
  • *
  • *

Note: vhost matches are case insensitive (as per convention).

Note: The nowww module ensures that is redirected to

Note: By allowing wildcard domain matching you can do cool things with your app, such as using the subdomains for usernames like github does.

If ~/webapps/vhosts/ exists and exports an array of hostnames, they will also be included.

API, Options, and Special Files

config.js - ~/webapps/config.js - user, githubAuth, port

  • user - the user that all applications should run as.
  • githubAuth - HTTP Basic Auth to be used by github.
  • yeswww - disables nowww redirection. - ~/webapps/ - runs whenever /github-hook is requested with the correct user:password

By default, these commands will be run:

git fetch
git pull
git submodule update
npm install

vhosts - ~/webapps/vhosts - where you should place your applications - ~/webapps/vhosts/ - the primary (production) vhost for your application. is an arbitrary example.

per-vhost aliases.js - ~/webapps/vhosts/ - any domain names exported here will be exported in addition to the name of the parent folder.

vhost submodule - ~/webapps/vhosts/ - include any commands here that should be run before (in addition to) the primary ~/webapps/ - this is particularly useful when your vhosts directory is a repository with multiple submodule applications.

per-vhost - ~/webapps/vhosts/ - include any commands here that should be run instead of the primary ~/webapps/


  • mime is listed as a top-level dependency of vhoster to allow you to extend connects mimetypes


If you have any apps that modify the prototype or attributes of the global connect you may want to store a seperate copy of connect in ~/webapps/vhosts/ rather than ~/webapps/node_modules.