Python code deployment with Fabric
written on Friday, May 6, 2011
So last night at the IndyPy meetup I gave a very impromptu talk on Fabric. It lasted maybe five minutes and afterward I really felt like I just did not do this great tool justice. In order to make up for that, I thought I'd dive in a little deeper to Fabric.
Why I am an idiot
First and foremost, I love Fabric because it lets me be lazy. For far too long while I was developing Yukmarks, I was manually typing things like:
local$ ssh my-ip-address.com remote$ git pull && sudo /etc/init.d/apache2 restart && ./manage.py dump_data && pg_dump >> foo.txt
You get the picture. It was ugly, and stupid, and time consuming, and I literally cannot believe that I spent all those calories typing those commands in over... and over... and over again.
Why I love Fabric
(In no way do I claim to use Fabric to its full potential, nor do I claim to be an expert, nor do I claim that my fabfile is fabulous. If you've got tips or corrections, please leave them in the comments.)
To make Fabric work, you just import the API and you're off:
from fabric.api import * from hosts import hosts, secret # I keep my hosts and auth data in a local file called hosts.py env.password = secret env.hosts = hosts def git_pull(): run("cd %s; . bin/activate; cd %s; git pull; ./manage.py schemamigration" " --auto yuk; ./manage.py migrate yuk;cp %s* %s;sudo /etc/init.d/apache2" " force-reload" % (domain_dir, appdir, css_dir, static_file_dir))
The above code is exactly what it looks like: a number of semicolon-separated shell commands. It's probably the most idiot-proof, time-saving thing I've ever used. Please see the below:
Stop typing so much. Fabric makes things ridiculously easy.
Edit 5/8/11: I actually reduced the complexity of my update_index() fabfile function quite a bit. I was doing a lot of really stupid chowning back and forth, which I've now fixed. Old:
def update_search(): run("cd %s; . bin/activate; cd %s; sudo chown matt:matt %s; sudo chown matt" ":matt %s*; ./manage.py update_index; sudo chown www-data:www-data %s; " "sudo chown www-data:www-data %s*; sudo /etc/init.d/apache2 force-reloa" "d" % (domain_dir, appdir, whoosh_dir, whoosh_dir, whoosh_dir, whoosh_dir))
def update_search(): run("sudo -u www-data /a/mattdeboard.net/bin/python %smanage.py update_inde" "x; sudo /etc/init.d/apache2 force-reload" % appdir)
p.s. In addition to Fabric, you'll definitely want to incorporate cron & creative use of your Makefile to make your life easier. Consult the github repo for Yukmarks.