Welcome to Underwear’s documentation!



Underwear is a library for easily deploying any Python-powered web application to one or more Linux servers. Underwear is configurable by a YAML template and takes care of installing packages, configuring web/WSGI servers, and securing the server.

What Problem Does Underwear Solve?

Despite the advent of configuration management tools such as Puppet, Chef, Ansible, and Salt, it remains difficult to deploy a web application because you have to first learn one of those tools and then write scripts in the tool’s domain-specific language.

Underwear makes deploying to a traditional Linux server stack as easy as deploying to Heroku by providing a pre-packaged, easily configurable library. Deployments can be executed simply by installing Underwear with pip, specifying the IP addresses of the server(s) to deploy to, then running a couple of commands.

Quick Start

After these ten steps your app should be completely configured, secured, and deployed to remote servers.

These instructions will be simplied in future releases as the library is further developed.

  1. Install Underwear to your virtualenv:

    pip install underwear
  2. Add ‘underwear’ to INSTALLED_APPS in your Django project. Underwear currently only supports Django (Flask and Bottle will be added in the 0.5 release).

  3. Create a deploy directory under your Django project:

    mkdir deploy; cd deploy
  4. Download the Fabric file for uploading SSH keys, YAML configuration template, and hosts file to your project under the deploy/ directory:

    wget https://raw.github.com/makaimc/underwear/master/underwear/deploy/fabfile.py
    wget https://raw.github.com/makaimc/underwear/master/underwear/deploy/underwear.yml
    wget https://raw.github.com/makaimc/underwear/master/underwear/deploy/hosts
  5. Fill in blank variables fields in fabfile.py.

  6. Execute the Fabric script (the script will prompt you for the non-root password):

    fab bootstrap_ansible
  7. Fill in blank fields and modify desired settings in the underwear.yml file so that Underwear knows where to install your web application.

  8. Fill in the hosts file with your servers’ IP addresses. For example, the file may look like the following:

  1. Deploy your application:

    python manage.py deploy
  2. Underwear will output each step in the deployment process to standard output as it happens.

  3. Access your application from the domain name you provided in the underwear.yml file.

License and Documentation

Underwear is free software under the MIT license.

Additional Underwear documentation can be found on Read the Docs.

About the Name “Underwear”

This library goes underneath your WSGI application to help you quickly deploy it to traditional servers. Otherwise no one knows you’re using it, and you can swap it out at any time for another deployment process when you outgrow the standard LAMP-stack setup.

There also weren’t any projects on GitHub by the name of underwear that had more than two stars and “underwear” was an open library name on PyPi :)


  • Automated WSGI application deployments to a web & database server
  • Configurable via a simple YAML template
  • Support for ad hoc deployment needs without SSH-ing into remote servers


Underwear is under active development and I use it personally for my Django and Flask side projects. However, the library is not polished or full of automated tests. The code needs a lot of clean up. Eventually the library will mature but for now it’s used to wrap Ansible with a simple Python interface and test what can be done with WSGI deployments.


At the command line:

$ easy_install underwear

Or, if you have virtualenvwrapper installed:

$ mkvirtualenv underwear
$ pip install underwear


To use Underwear in a project:

import underwear

SSH keys

Ansible runs over SSH, so we need a way to bootstrap SSH connections through a non-root user.

One way to automate these first few steps is with Fabric. The fabfile.py.template contains one public function, bootstrap_ansible. bootstrap_ansible calls the other functions to create a non-root user with sudo privileges, upload public keys for deployment, and lock down root from logging in.

Copy fabfile.py.template to fabfile.py, fill in the commented fields at the top of the script, then run the script with:

fab bootstrap_ansible

Right now the script will prompt you for the password the non-root user should be created with. I’ll automate that manual step away later.


Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.

You can contribute in many ways:

Types of Contributions

Report Bugs

Report bugs at https://github.com/makaimc/underwear/issues.

If you are reporting a bug, please include:

  • Your operating system name and version.
  • Any details about your local setup that might be helpful in troubleshooting.
  • Detailed steps to reproduce the bug.

Fix Bugs

Look through the GitHub issues for bugs. Anything tagged with “bug” is open to whoever wants to implement it.

Implement Features

Look through the GitHub issues for features. Anything tagged with “feature” is open to whoever wants to implement it.

Write Documentation

Underwear could always use more documentation, whether as part of the official Underwear docs, in docstrings, or even on the web in blog posts, articles, and such.

Submit Feedback

The best way to send feedback is to file an issue at https://github.com/makaimc/underwear/issues.

If you are proposing a feature:

  • Explain in detail how it would work.
  • Keep the scope as narrow as possible, to make it easier to implement.
  • Remember that this is a volunteer-driven project, and that contributions are welcome :)

Get Started!

Ready to contribute? Here’s how to set up underwear for local development.

  1. Fork the underwear repo on GitHub.

  2. Clone your fork locally:

    $ git clone git@github.com:your_name_here/underwear.git
  3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:

    $ mkvirtualenv underwear
    $ cd underwear/
    $ python setup.py develop
  4. Create a branch for local development:

    $ git checkout -b name-of-your-bugfix-or-feature

    Now you can make your changes locally.

  5. When you’re done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:

    $ flake8 underwear tests
    $ python setup.py test
    $ tox

    To get flake8 and tox, just pip install them into your virtualenv.

  6. Commit your changes and push your branch to GitHub:

    $ git add .
    $ git commit -m "Your detailed description of your changes."
    $ git push origin name-of-your-bugfix-or-feature
  7. Submit a pull request through the GitHub website.

Pull Request Guidelines

Before you submit a pull request, check that it meets these guidelines:

  1. The pull request should include tests.
  2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.
  3. The pull request should work for Python 2.6, 2.7, and 3.3, and for PyPy. Check https://travis-ci.org/makaimc/underwear/pull_requests and make sure that the tests pass for all supported Python versions.


To run a subset of tests:

$ python -m unittest tests.test_underwear


Development Lead


None yet. Why not be the first?


This document proposes how Underwear will evolve over the course of 2014.


  • Add new parser for command line options


  • Add flags to configure how a Django app should be deployed.
  • Clean up ugly Django management command integration.
  • Create unit tests for core deployment flow.
  • Make deployer username configurable


  • Command line integration to run “underwear deploy” instead of only invoking from Django manage.py
  • Adding support for deploying Flask apps.


0.4.5 (2014-06-17)

  • Updated to work with the latest Ansible release under the covers (1.6.3).
  • Fixed a bug with evaluating conditional for postgresql backend.
  • Fixed issue where fail2ban wouldn’t be found on a system because the apt cache was not updated.

0.4.4 (2014-01-05)

  • Changing Django management command defaults to deploy directory within the project instead of your ~/.ssh key directory.
  • New option in underwear.yml to deploy to MySQL or PostgreSQL.

0.4.3 (2014-01-02)

  • Adding toggle for whether South should be used with a Django project (django_use_south) and a toggle for whether a fixtures file should be loaded (django_fixtures_file).

0.4.2 (2013-12-30)

  • Added toggle to flip whether or not SSL should be used with Nginx (deploy_ssl).

0.4.0 (2013-12-26)

  • Release now allows for 2 server web app deployments (one web server and one database server).
  • Fixes issues with Supervisor template and Django environment variables.
  • Includes templates required to tell the library where to deploy the application.

0.3.0 (2013-12-24)

  • First release on PyPI.

0.2.0 (2013-12-16)

  • Added initial working Ansible scripts for deployment.

0.1.0 (2013-12-16)

  • Initial codebase with Python package

Indices and tables