18F/foia-hub — pull request #48 by konklone (2014-09-16 05:45:21+00:00)
Title: Fabric deployment script

I've got a working deploy path with `fabric` that can stop, start, restart the application, and deploy new code on demand. This PR is **downstream** of #47, so merge that one first.

This does a few things, including some fixes along the way. Would love @khandelwal's eyes on the fixes, since I think they relate to his work in #46.

Note that `fabric` requires Python 2.X, and our app requires Python 3.X. I'm managing this by having a `fab` virtualenv with a Python 2.X frozen inside it, and switching to it before running `fab` commands.

* Moves the gunicorn config into a `deploy/` directory, to a (git ignored) `deploy/config.py` file. A `config.py.example` file sits next to it, which can be copied and adapted.
* Adds a `fabfile.py` that can be used to deploy and control the application. Commands:

```bash
fab start # start stopped app
fab stop # stop running app
fab restart # restart running app (will update changed code, will not update changed environment)
fab deploy # deploy when the app is running
fab deploy_cold # deploy when the app is stopped
```

* Tore out hair figuring out why fabric wasn't starting `gunicorn` properly, eventually [figured out](http://stackoverflow.com/questions/17748234/unable-to-start-gunicorn-with-fabric#comment26533754_17986215) that fabric requires `pty=False` for [background processes](http://docs.fabfile.org/en/1.7/usage/interactivity.html). (This has never affected me before when using fabric to run `unicorn` processes in Ruby-land.)
* Commented out `ALLOWED_HOSTS` in `settings/base.py` because it was somehow obscuring the `ALLOWED_HOSTS` set in `settings/production.py` from being seen. @khandelwal, any ideas why this was? `production.py` imports from `.base.*` before anything, seems like it should be overwritten.
* Fixed bug in `settings/production.py`, added the missing dot-prefix in `from .local_settings import *`.

Not in source control, but done on our server:

* Created a production `local_settings.py` file, pointing to the server's own Postgres database.
* Created a production gunicorn `config.py` file, configured to launch 2 worker processes.
* Began logging gunicorn access and error log output.
* Cleared database, ran migrations, reloaded data using the latest code and data.

If this is good, I can proceed to adding deploy webhooks, and updating fabric with commands to control them.