Drama-free Django =============
This project aims to make Django projects easy to deploy. It provides a command-line tool for bundling your project and it's dependencies into a zip file (called a "build") and later modifying the build to insert environment-specific configuration (called a "release"). These definitions of "build" and "release" are inspired by chapter 5 of The Twelve Factor App:
http://12factor.net/build-release-run
This has only been tested on 64-bit Linux, with Python 2.7. The system that generates builds needs to have 'pip' and 'wheel' installed, and whatever else is needed to build your Python dependencies. Servers you deploy to must only have a Python 2.7 interpreter, and a daemon that can run WSGI apps, like Apache with mod_wsgi.
It's recommended that you use a recent version of pip, since its built-in caching speeds things up quite a bit.
This package isn't in PyPI yet-- in the meantime, you should be able to install it with::
pip install git+https://github.com/cfpb/drama-free-django.git
Make a build -----
usage: no-drama build [--aux AUX] [-f] [-h] [-r R] [--static STATIC] project_path name label
positional arguments:
project_path source directory containing project code
name name for this project
label a label for this build, maybe a build ID or version number
optional arguments:
-h, --help show this help message and exit
-f force rebuild even if target archive already exists
--aux add an additional source directory
-r add an external requirements file
--static add an additional static files directory
to generate a build of the current cfgov-refresh, you would (after running the front-end build process as documented in their README), run:
no-drama build cfgov-refresh/cfgov cfgov-refresh/requirements/base.txt cfgov <build label>
Where "build label" could refer to a version or tag of your project, or the build ID generated by you continuous integration server.
If all goes well, a zip file will be created in your current directory, named like:
cfgov_<build label>.zip
Make a release -----
usage: no-drama release [-h] [--paths PATHS]
[--requirements_file REQUIREMENTS_FILE]
[--prepend-wsgi PREPEND_WSGI]
[--append-wsgi APPEND_WSGI]
build_zip vars slug
positional arguments:
build_zip path to a zip file generated with 'no-drama build'
vars JSON dictionary of env variables
slug a label for this release
optional arguments:
-h, --help show this help message and exit
--paths PATHS json file for overriding default paths
--requirements_file REQUIREMENTS_FILE
just like you would 'pip install -r'. Lets you add
more wheels to the build
--prepend-wsgi PREPEND_WSGI
text file w/ additional python code to modify the
environment before the wsgi 'application' is created
--append-wsgi APPEND_WSGI
text file w/ additional python code to modify the wsgi
'application'
To make a release, you need a zip file as generated by the 'build' step above, a JSON file containing a dictionary of variables (these get injected into os.environ), and a slug to describe the environment (for example "production").
Put together, that looks like:
no-drama release cfgov_r30.zip vars.json production
the file generated from the above will be:
cfgov_r30_production.zip
Deploy a release -----
A release is not very opinionated about where exactly it sits on the filesystem, though it does have some built-in assumptions that are worth explaining. The most interesting, is that it expects to be two levels below whatever directory you've devoted to the project.
In other words, it anticipates a file layout like this:
/srv/<project name>
/srv/<project name>/current/ <--- this is a symlink to the current active build
/srv/<projecy name>/static.in <--- A place to put extra static files (optional)
/srv/<project name>/versions/
/srv/<project name>/versions/<build label>
/srv/<project name>/versions/<previous build labels>
...
both "/srv/<project name>" and "versions" can be anything.
It's up to your (or your system administrator) to created the directories that releases get deployed to.
To deploy a release, you: - unzip it into the directory where you want to put it (in the layout above, this is "versions") - run activate.sh
While you wait, a new virtualenv will be created, static files will be collected, and the 'current' symlink will be updated.
Afterwards, you may want to run 'django-admin migrate' to update your database, and make sure the permissions allow your server to access all of the release files.
Web server configuration -----
It's impossible to describe every deployment scenario, but at minimum, you must:
- configure your WSGI server to use the file at current/wsgi.py, and include current/venv/lib/python2.7/site-packages
- Alias /static/ (or whatever value you are using for STATIC_URL) to current/static
On RHEL6, with Apache+mod_wsgi (via software collections) in daemon mode, this might look like:
WSGIDaemonProcess my_cool_daemon processes=4 threads=15 display-name=%{GROUP} python-path=/srv/cfgov/current/venv/lib/python2.7/site-packages
WSGIProcessGroup my_cool_daemon
WSGIScriptAlias / /srv/cfgov/current/wsgi.py
Alias /static/ /srv/cfgov/current/static/
<Directory /srv/cfgov/current/>
Require all granted
</Directory>
Also with mod_wsgi, it's recommended that you set an empty virtualenv as your WSGIPythonHome.
http://modwsgi.readthedocs.org/en/develop/user-guides/virtual-environments.html#baseline-environment
We've got you covered:
WSGIPythonHome /srv/cfgov/current/empty_venv
Document any known significant shortcomings with the software.
If you have questions, concerns, bug reports, etc, please file an issue in this repository's Issue Tracker.