docs: function serve(app, couch) {
    var url = require('url');
    var port = 3000,
        staticDir = 'attachments',
        tmpDir = '/tmp/couchapp-compile-' + process.pid,
        logDbRewrites = false;
    var arg;
    while(arg = process.argv.shift()){
      if(arg == '-p'){
        port = parseInt(process.argv.shift());
      }
      if(arg == '-d'){
        staticDir = process.argv.shift();
      }
      if(arg == '-l'){
        logDbRewrites = true;
      }
    }
    var dbUrlObj = url.parse(couch);
  
    var proxyPaths = {}
    var dbPrefix = '../../';
    for (var i in app.doc.rewrites){
      var rw = app.doc.rewrites[i];
      // Rewrites starting with '../../' are proxied to the database
      if (rw.to.indexOf(dbPrefix) == 0){
        var proxyPath = rw.from;
        if(proxyPath[proxyPath.length -1] == '*') {
          proxyPath = proxyPath.substring(0,proxyPath.length-1)
        }
        var dbPath = rw.to.substring(dbPrefix.length);
        if(dbPath[dbPath.length - 1] == '*'){
          dbPath = dbPath.substring(0,dbPath.length-1)
        }
        if(dbPath.indexOf('*') >=0 ){
          if(logDbRewrites){
            console.log("Don't know how to proxy '" + rw.from + "' to CouchDB at " + rw.from );
          }
        } else {
          proxyPaths[proxyPath] =
            dbUrlObj.protocol + '//' + dbUrlObj.host +
            path.normalize(dbUrlObj.pathname + dbPath);
            if(logDbRewrites){
              console.log("Proxying rewrite '" + proxyPath + "' to CouchDB at " + proxyPaths[proxyPath] );
            }
        }
      }
    }
  
    var connect = require('connect');
    var httpProxy = require('http-proxy'),
        connect   = require('connect'),
        logger = require('morgan'),
        serveStatic = require('serve-static'),
        errorHandler = require('errorhandler'),
        connectCompiler;
    try{
        connectCompiler = require('connect-compiler');
    } catch(e) {}
  
  
    var proxy = httpProxy.createProxyServer({
      target: {
        host: dbUrlObj.host,
        hostname: dbUrlObj.hostname,
        port: dbUrlObj.port,
        https: dbUrlObj.protocol == 'https:',
      }
    });
    var app = connect()
      .use(logger('dev'))
      .use(serveStatic(staticDir));
    if(connectCompiler){
      console.log('Will compile assets with connect-assets.');
      var ignore = [];
      var quote = function(str) {
        return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
      }
      for(var prefix in proxyPaths){
        ignore.push(quote(prefix));
      }
      if(ignore.length){
        //console.log("Asset compile ignore paths:", '^(' +  ignore.join('|') + ')');
        ignore  = new RegExp('^(' +  ignore.join('|') + ')');
      } else {
        ignore = null;
      }
      app.use(connectCompiler({
        enabled: ['coffee'] ,
        src: staticDir,
        dest: tmpDir,
        ignore :  ignore,
      }))
      .use(serveStatic(tmpDir));
    }
    app.use(function(req, res, next) {
        for(var prefix in proxyPaths){
          var dbPath = proxyPaths[prefix];
          if (req.url.indexOf(prefix) === 0) {
            var dbURL = req.url.replace(prefix,dbPath);
            if(logDbRewrites){
              console.log("*** ", req.url , ' -> ', dbURL);
            }
            req.url = dbURL;
            req.headers['host'] = dbUrlObj.host;
            proxy.proxyRequest(req, res);
            return;
          }
        }
        var body = '404 Not found.\nNo static file or db route matched.';
        res.statusCode = 404;
        res.setHeader('Content-Length', body.length);
        res.end(body);
       })
      .use(errorHandler())
      .listen(port);
    console.log("Serving couchapp at: http://0.0.0.0:" + port +"/");
  
    //Cleanup the temp directory on exit
    var cleanup = function(){
      var rmDir = function(dirPath) {
        try { var files = fs.readdirSync(dirPath); }
        catch(e) { return; }
        if (files.length > 0)
          for (var i = 0; i < files.length; i++) {
            var filePath = dirPath + '/' + files[i];
            if (fs.statSync(filePath).isFile())
              fs.unlinkSync(filePath);
            else
              rmDir(filePath);
          }
        fs.rmdirSync(dirPath);
      };
      rmDir(tmpDir);
    };
    process.on('exit',cleanup);
    process.on('SIGINT',function(){
      cleanup()
      process.exit();
    });
  }