Can nginx start apache on demand?

I have an "archive" server for old sites that no longer are being used, but I want to keep them online as part of my CV/Portfolio.

They require different apache and php versions and setups, so I am running multiple apaches on different ports, behind a nginx reverse proxy.

However, it is not very often that those sites have visitors. It might take days or even weeks between the visits, so I think it is a big wast of memory and cpu to have all those apache instances running all the time.

What I would like to do is to make nginx start the appropriate apache server on demand. Maybe something like this:

  1. Incoming http request to nginx.
  2. nginx checks if an apache server is responding on it's tcp port.
  3. If apache is not responding: run some script to start apache.
  4. When apache starts responding, reverse proxy the http request to apache.

I want the apache daemon to be loaded with PHP as module. I want the experience to be fast and good when a visiter is surfing the sites, however, a couple of seconds of loading time on the first request is no problem. Some of the sites are very AJAX intensive, so loading apache for every request is not an option.

I do not find any obvious way to do this. Does anyone have any ideas or experiences on a similar setup? Are there other reverse proxy softwares (than nginx) that would do this?

(Of course, I would also need a way to shut down apache on inactivity, but that is quite simple with a cron job just checking if something has happend in apache's access.log.)

Btw.. The server is running Debian Lenny.

Edit / my solution:

I solved this problem by scripting with https://github.com/nodejitsu/node-http-proxy for node.js.

// I'm using http-proxy to make the proxying:
var server = httpProxy.createServer(function (req, res, proxy) {
  var domain = getDomain(req);
  proxy.proxyRequest(req, res, {
    host: '127.0.0.1',
    port: configuration[domain].port
  });
}).listen(80);

// And a error handler, which will start apache on deman:

server.proxy.on('proxyError', function(err, req, res) {
  if (err.errno == 'ECONNREFUSED') {
    // Start apache using exec()
  }
});

Solution 1:

An alternative approach might be to start apache via a script-call defined in inetd.conf.

This approach is detailed in the article Starting Lighttpd on demand, which although Lighttpd-oriented, might possibly be made to apply to your version of apache.

The article above contains the script for starting the Lighttpd web-server on reference to a given port, where lighttpd needs probably be substituted to apachectl. It also details some ideas on how it can also be automatically shut-down so it doesn't stay running forever.

If this approach is applicable to your case, you might consider adding your inetd.conf configuration-line and scripts to your post for future readers.

Solution 2:

You could run apache via inetd (or xinetd). See the ServerType directive in the apache config docs.

When running a TCP service via inetd, you'll start up a process per request. So when there are no requests, there are no apache processes. inetd can listen on all of the appropriate ports.