Fabric Bolt¶
Fabric Bolt is a Python/Django project that allows you to deploy code stored in source control (a project) to a target server (host). Fabric Bolt provides convenient web interfaces to configure both the projects and the hosts. Additionally, deployment history and logs are stored so that you know who deployed what on which day.
Users Guide¶
Installing Fabric Bolt¶
To run Fabric Bolt you’ll need:
- A UNIX-based operating system
- Python 2.7
- python-setuptools, python-dev, libxslt1-dev, libxml2-dev
- A real database (PostgreSQL is preferred, MySQL also works)
You can run Fabric Bolt on an existing server/host, but this guide will assume that Fabric Bolt is the only thing running on the server.
This guide will step you through setting up a virtualenv, installing the required packages, and configuring the basic web service.
Quickstart¶
If you are familiar with running a django project that has been pip installed, you can use these steps to get Fabric Bolt running. Otherwise skip this and use the detailed directions below.
Install:
pip install fabric-bolt
Initialize settings file. (To specify file location, enter as the second argument.):
fabric-bolt init [~/.fabric-bolt/settings.py]
Modify generated settings file to enter database settings.
Migrate db:
fabric-bolt migrate
Run:
fabric-bolt runserver
Note:
If you have created a settings file at a different location than the default, you can use the –config option on any command (besides the init command) to specify the custom file path. Alternatively, you can set an env variable: FABRIC_BOLT_CONF.
Setting up an Environment¶
The first thing you’ll need is the Python virtualenv package. You probably already have this, but if not, you can install it with:
easy_install -UZ virtualenv
Once that’s done, choose a location for the environment, and create it with the virtualenv command. For our guide, we’re going to choose /www/fabric-bolt/:
virtualenv /www/fabric-bolt/
Finally, activate your virtualenv:
source /www/fabric-bolt/bin/activate
Note
Activating the environment adjusts your PATH, so that things like easy_install now install into the virtualenv by default.
Install Fabric Bolt¶
Once you have the environment setup you can install Fabric Bolt and all its dependencies with pip (virtualenv comes with a copy of pip which gets copied into every new environment you create):
pip install fabric-bolt
Don’t be worried by the amount of dependencies Fabric Bolt has. Our philosophy is to use the right tool for the job, and to not reinvent them if they already exist.
Initializing the Configuration¶
After Fabric Bolt has been installed, you will need to create and configure a settings.py file. We have packaged Fabric Bolt with a utility to generate a settings.py file for you:
fabric-bolt init
Or, optionally, you can provide a path to the settings file:
fabric-bolt init /etc/fabric-bolt/settings.py
The settings file will be located at ~/.fabric-bolt/settings.py. And should be edited for your database configuration:
vi ~/.fabric-bolt/settings.py
The configuration for the server is based on the settings file, which contains a basic Django project configuration:
# ~/.fabric-bolt/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', # We suggest PostgreSQL for optimal performance
'NAME': 'fabric-bolt',
'USER': 'postgres',
'PASSWORD': '',
'HOST': '',
'PORT': '',
'OPTIONS': {
'autocommit': True,
}
}
}
Configure Outbound Mail¶
Several settings exist as part of the Django framework which will configure your outbound mail server. For the standard implementation, using a simple SMTP server, you can simply configure the following:
EMAIL_HOST = 'localhost'
EMAIL_HOST_PASSWORD = ''
EMAIL_HOST_USER = ''
EMAIL_PORT = 25
EMAIL_USE_TLS = False
Being that Django is a pluggable framework, you also have the ability to specify different mail backends. See the official Django documentation for more information on alternative backends.
Running Migrations¶
Fabric Bolt provides an easy way to run migrations on the database on version upgrades. Before running it for the first time you’ll need to make sure you’ve created the database:
# If you're using Postgres, and kept the database ``NAME`` as ``fabric-bolt``
$ createdb -E utf-8 fabric-bolt
Once done, you can create the initial schema using the migrate command:
$ fabric-bolt migrate
Next, create a super user by doing the following:
# create a new user
$ fabric-bolt --config=/etc/fabric-bolt/settings.py createsuperuser
All schema changes and database upgrades are handled via the migrate command, and this is the first thing you’ll want to run when upgrading to future versions of Fabric Bolt.
Note
Internally, this uses South to manage database migrations.
Starting the Web Service¶
FOR TESTING, Fabric Bolt can be run with the basic webserver that comes packaged with django. This can be started with fabric-bolt runserver, or if you’re using a custom settings file
# Fabric Bolt's server runs on port 8000 by default. Make sure your client reflects
# the correct host and port!
fabric-bolt --config=/etc/fabric-bolt/settings.py runserver
You should now be able to test the web service by visiting http://localhost:8000/.
You should NOT run Fabric Bolt in production with runserver. Follow the directions below to run Fabric Bolt with uWSGI and Nginx.
Setup a Reverse Proxy¶
By default, Fabric Bolt runs on port 8000. Even if you change this, under normal conditions you won’t be able to bind to port 80. To get around this (and to avoid running Fabric Bolt as a privileged user, which you shouldn’t), we recommend you setup a simple web proxy.
Proxying with Apache¶
Apache requires the use of mod_proxy for forwarding requests:
ProxyPass / http://localhost:8000/
ProxyPassReverse / http://localhost:8000/
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https" env=HTTPS
You will need to enable headers, proxy, and proxy_http apache modules to use these settings.
Proxying with Nginx¶
You’ll use the builtin HttpProxyModule within Nginx to handle proxying:
location / {
proxy_pass http://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
See Configuring Fabric Bolt with Nginx for more details on using Nginx.
Enabling SSL¶
If you are planning to use SSL, you will also need to ensure that you’ve enabled detection within the reverse proxy (see the instructions above), as well as within the Fabric Bolt configuration:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
Running Fabric Bolt as a Service¶
We recommend using whatever software you are most familiar with for managing Fabric Bolt processes. For us, that software of choice is Supervisor.
Configure supervisord¶
Configuring Supervisor couldn’t be more simple. Just point it to the fabric-bolt executable in your virtualenv’s bin/ folder and you’re good to go.
[program:fabric-bolt-web]
directory=/www/fabric-bolt/
command=/www/fabric-bolt/bin/fabric-bolt start
autostart=true
autorestart=true
redirect_stderr=true
Indices and tables¶
Configuring Fabric Bolt with Nginx¶
Nginx provides a very powerful platform for running in front of Fabric Bolt.
Below is a sample configuration for Nginx:
http {
server {
listen 80;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
# keepalive + raven.js is a disaster
keepalive_timeout 0;
# use very aggressive timeouts
proxy_read_timeout 5s;
proxy_send_timeout 5s;
send_timeout 5s;
resolver_timeout 5s;
client_body_timeout 5s;
# buffer larger messages
client_max_body_size 150k;
client_body_buffer_size 150k;
location / {
proxy_pass http://localhost:8000;
}
}
}
Proxying uWSGI¶
We recommend that you setup uWSGI to run Fabric Bolt (rather than relying on the built-in django webserver).
Within your uWSGI configuration, you’ll need to export your configuration path as well the wsgi.py module:
[uwsgi]
env = FABRIC_BOLT_CONF=/etc/fabric-bolt/settings.py
module = wsgi.py
; spawn the master and 4 processes
http-socket = :8000
master = true
processes = 4
; allow longer headers for raven.js if applicable
; default: 4096
buffer-size = 32768
Overview¶
Hosts¶
Hosts are simply an IP address or DNS name. Hosts are globally defined and can be targets for several projects in Fabric Bolt.
Host Roles¶
It is common to have hosts that perform a particular role. For instance we might have a host that is a database server, one that is a web server, and one that is an app server (performing background tasks). By specifying what role each host plays, Fabric Bolt can customize the commands that run against each host during a deployment. So database servers have migrations run against them and web servers have their static assets collected to a central place, but not vice versa.
Sometimes a particular host serves as a particular role for one project, but a different role for another project. So roles are assigned to hosts when you configure them on a project.
Projects¶
Projects are simply a deployment configuration. Each project can define a top level Project Configuration that includes things like the source control location, source code branch to use, host connection credentials, etc.
Projects also define their stages (more on stages below).
Project Stages¶
It is common for web developers to deploy their projects to a test/development/staging host for review before deploying to production. In Fabric Bolt we refer to those pieces of a deployment workflow as stages. In other words, we would always go through the following deployment stages for a particular project revision:
test -> staging -> production
Because stages can be as unique as the project code base itself, stages are configured per project and define stage specific configuration values that can override project configurations. Each Stage is simply a Host, Host Role, and Configuration values.
Deployment Tasks¶
Fabric Bolt uses a python package called Fabric to provide the core functionality of connecting to a remote host and executing shell commands on that host to perform a deployment. Because deployments typically have a large collection of commands that must be executed on a remote host, and those commands are usually grouped together to perform a particular deployment task, Fabric Bolt leverages Fabric tasks as deployment tasks. A deployment task is the same thing as a Fabric task, which is a collection of remote commands to run.
Deployment tasks are defined in a fabfile.py file that ships with Fabric Bolt. But you can provide your own fabfile.py if you want to customize the deployment tasks for a project.
Your deployment tasks are defined at the project level, but because Project Stages are the full configuration of a project and target host, deployment tasks are run from the project stage page.
Putting it Together¶
If we diagram this simple structure, it looks something like this:
Project
|_ Configurations (git repo, git branch, code_root, etc.)
|_ Deployment Tasks
|
|_ Test Stage
| |_ Hosts (w/ roles)
| |_ Configurations (git branch, settings_file, etc.)
|
|_ Production Stage
|_ Hosts (w/ roles)
|_ Configurations (git branch, settings_file, etc.)
Running a Deployment¶
Deployments are actually run against a project stage, since project stages fully define both the project and target hosts fully. To run a deployment:
- Define your hosts
- Create a project
- Configure the project with the source control repo to be deployed (and any other necessary configs)
- Add a stage
- Configure the stage with at least one host
- Select a deployment task to run against the stage
- Review the deployment details and provide comments about the deployment
- Click “Go!”
Deployments run in a background thread so you can navigate away from the deployment detail screen while a deployment is running. Fabric Bolt tracks the status of the deployment so that you can always come back later and check for success. However, from the deployment detail screen you can watch the live log of what commands are being run on the remote hosts while a deployment is running. After the deployment is complete the log is available for review. This is particularly helpful for resolving issues with failed deployments.
Users¶
Users are configured in the system with one of three roles. For details on these roles see the http://yourdomain.com/user/permissions/ page.
FAQ¶
What is the difference between a role and a host?
Fabric Bolt hosts are globally known servers that Fabric Bolt can deploy to. When configuring a stage you need to add servers to it in order to deploy it. Each time you add a host you give it a role like app. This host is then used by the stage as a application-server. You can also create your own custom roles like ferret_server and reference this role in a task.
How do I run a deployment?
Fabric Bolt uses the concept of Project Stages to allow for sufficient customization for a deployment. You will need to configure at least one host, one project, and one project stage. Once those items are properly configured you can select a deployment task to run on the Project Stage page.
Developers¶
Contributing¶
Want to contribute back to Fabric Bolt? This page describes the general development flow, our philosophy, the test suite, and issue tracking.
COMING VERY SOON!!
Reference¶
Changelog¶
- v 0.1 (in development)
- Added support for using the fabfile in each project’s repo
- Added “launch window” feature
- Added experimental socket.io support for deployment output. (use SOCKETIO_ENABLED setting)
- Fixed an issue where deleted projects showed up in graphs and sidebar (issue #67)
- Fixed an issue where admins could not set user’s user level. (issue #64)
- Added alias to hosts model. (thanks Hedde!)
- Added note in README about creating a super user (thanks madazone!)
- Fixed injection security bug in fab command
- Using virtualenv to run project fabfiles
- Added task argument support!
- Fabric task lists are now cached per project. Invalidate the cache on the project detail page.
- Upgraded to django 1.7. IMPORTANT: run fabric-bolt migrate.