[wip] Spawning pool

Time to shave off that final 2-second delay. This PR implements #32 by pre-launching a configured ~~*(by which I mean hardcoded to "3")*~~ set of containers and handing them out to incoming requests. When a container is culled for inactivity, it's scrapped and a new one is launched and added to the pool in its place.

If you hit `orchestrate.py` with a path already set (using a stale link, for example, or an appear.in-style link like #67 implements), you have a personal container created and linked as it happens now.

/cc @rgbkrk so he can see just how terrible this is right now, and suggest embetterment techniques :wink:

- [x] Remove any remaining now-dead code. Container launching should be centralized and managed by the SpawnPool.
- [x] Get culling working again.
- [x] Fix the race condition in the culling routine that causes the pool to grow without bound if the culling interval is shorter than the time that it takes to cull a container.
- [x] Display a friendlier message (meaning, not a stack trace) when the node is out of capacity. A non-200 response code might be useful for upstream load balancing, too. If it's possible, it would be neat to do things like fail over to the next node when 500s are received.
- [x] Since we're using the pool size as an absolute capacity, defaulting to zero is not optimal. `make dev` should probably default to something like 3, maybe.
- [x] Clean out existing containers and proxy entries on restart of `orchestrate.py`.
- [x] Catch and log Docker API errors.
- [x] Change the "I'm full" page to indicate that it'll also auto-refresh for you to try again.
- [x] Refactor `_clean_orphaned_containers`. Bring more of that functionality into `cull` as well, so we also clean up zombies and dead proxy entries periodically.
Oh, I was thinking we could have a set of keyword parameters `.format()`'ed in to the command, so you'd provide a template like `"--NotebookApp.base_url=/{base_path}`.