# cherrypy.process.servers module

Starting in CherryPy 3.1, cherrypy.server is implemented as an Engine Plugin. It’s an instance of `cherrypy._cpserver.Server`, which is a subclass of `cherrypy.process.servers.ServerAdapter`. The `ServerAdapter` class is designed to control other servers, as well.

## Multiple servers/ports

If you need to start more than one HTTP server (to serve on multiple ports, or protocols, etc.), you can manually register each one and then start them all with engine.start:

    s1 = ServerAdapter(
        cherrypy.engine,
        MyWSGIServer(host='0.0.0.0', port=80)
    )
    s2 = ServerAdapter(
        cherrypy.engine,
        another.HTTPServer(host='127.0.0.1', SSL=True)
    )
    s1.subscribe()
    s2.subscribe()
    cherrypy.engine.start()

## FastCGI/SCGI

There are also FlupFCGIServer and FlupSCGIServer classes in `cherrypy.process.servers`. To start an fcgi server, for example, wrap an instance of it in a ServerAdapter:

    addr = ('0.0.0.0', 4000)
    f = servers.FlupFCGIServer(application=cherrypy.tree, bindAddress=addr)
    s = servers.ServerAdapter(cherrypy.engine, httpserver=f, bind_addr=addr)
    s.subscribe()

The cherryd startup script will do the above for you via its `-f` flag. Note that you need to download and install flup yourself, whether you use `cherryd` or not.

### FastCGI

A very simple setup lets your cherry run with FastCGI. You just need the flup library, plus a running Apache server (with `mod_fastcgi`) or lighttpd server.

#### CherryPy code

hello.py:

    #!/usr/bin/python
    import cherrypy

    class HelloWorld:
        '''Sample request handler class.'''
        @cherrypy.expose
        def index(self):
            return "Hello world!"

    cherrypy.tree.mount(HelloWorld())
    # CherryPy autoreload must be disabled for the flup server to work
    cherrypy.config.update({'engine.autoreload.on':False})

Then run /deployguide/cherryd with the ‘-f’ arg:

    cherryd -c <myconfig> -d -f -i hello.py

#### Apache

At the top level in httpd.conf:

    FastCgiIpcDir /tmp
    FastCgiServer /path/to/cherry.fcgi -idle-timeout 120 -processes 4

And inside the relevant VirtualHost section:

    # FastCGI config
    AddHandler fastcgi-script .fcgi
    ScriptAliasMatch (.*$) /path/to/cherry.fcgi$1

#### Lighttpd

For Lighttpd you can follow these instructions. Within `lighttpd.conf` make sure `mod_fastcgi` is active within `server.modules`. Then, within your `$HTTP["host"]` directive, configure your fastcgi script like the following:

    $HTTP["url"] =~ "" {
      fastcgi.server = (
        "/" => (
          "script.fcgi" => (
            "bin-path" => "/path/to/your/script.fcgi",
            "socket"          => "/tmp/script.sock",
            "check-local"     => "disable",
            "disable-time"    => 1,
            "min-procs"       => 1,
            "max-procs"       => 1, # adjust as needed
          ),
        ),
      )
    } # end of $HTTP["url"] =~ "^/"

Please see Lighttpd FastCGI Docs for an explanation of the possible configuration options.

class cherrypy.process.servers.FlupCGIServer(*args, **kwargs)

  Bases: `object`

  Adapter for a flup.server.cgi.WSGIServer.

  start()

    Start the CGI server.

  stop()

    Stop the HTTP server.

class cherrypy.process.servers.FlupFCGIServer(*args, **kwargs)

  Bases: `object`

  Adapter for a flup.server.fcgi.WSGIServer.

  start()

    Start the FCGI server.

  stop()

    Stop the HTTP server.

class cherrypy.process.servers.FlupSCGIServer(*args, **kwargs)

  Bases: `object`

  Adapter for a flup.server.scgi.WSGIServer.

  start()

    Start the SCGI server.

  stop()

    Stop the HTTP server.

class cherrypy.process.servers.ServerAdapter(bus, httpserver=None, bind_addr=None)

  Bases: `object`

  Adapter for an HTTP server.

  If you need to start more than one HTTP server (to serve on multiple ports, or protocols, etc.), you can manually register each one and then start them all with bus.start:

      s1 = ServerAdapter(bus, MyWSGIServer(host='0.0.0.0', port=80))
      s2 = ServerAdapter(bus, another.HTTPServer(host='127.0.0.1', SSL=True))
      s1.subscribe()
      s2.subscribe()
      bus.start()

  _get_base()
  _start_http_thread()

    HTTP servers MUST be running in new threads, so that the main thread persists to receive KeyboardInterrupt’s. If an exception is raised in the httpserver’s thread then it’s trapped here, and the bus (and therefore our httpserver) are shut down.

  property bound_addr

    The bind address, or if it’s an ephemeral port and the socket has been bound, return the actual port bound.

  property description

    A description about where this server is bound.

  restart()

    Restart the HTTP server.

  start()

    Start the HTTP server.

  stop()

    Stop the HTTP server.

  subscribe()
  unsubscribe()
  wait()

    Wait until the HTTP server is ready to receive requests.

class cherrypy.process.servers.Timeouts

  Bases: `object`

  free = 1
  occupied = 5

cherrypy.process.servers._safe_wait(host, port)

  On systems where a loopback interface is not available and the server is bound to all interfaces, it’s difficult to determine whether the server is in fact occupying the port. In this case, just issue a warning and move on. See issue #1100.