{"id":2213,"date":"2010-11-05T22:46:26","date_gmt":"2010-11-06T03:46:26","guid":{"rendered":"http:\/\/blogs.terrorware.com\/geoff\/?p=2213"},"modified":"2010-11-09T22:47:43","modified_gmt":"2010-11-10T03:47:43","slug":"really-it%e2%80%99s-worth-it","status":"publish","type":"post","link":"http:\/\/blogs.terrorware.com\/geoff\/2010\/11\/05\/really-it%e2%80%99s-worth-it\/","title":{"rendered":"Really, It\u2019s Worth It"},"content":{"rendered":"<p><em>This was <a href=\"http:\/\/localfourth.com\/2010\/11\/05\/really-its-worth-it\/\">originally posted<\/a> on the <a href=\"http:\/\/www.localfourth.com\/\">Local Fourth<\/a> blog as part of my participation in a community media innovation project at the <a href=\"http:\/\/www.medill.northwestern.edu\/\">Medill School of Journalism<\/a>.<\/em><\/p>\n<p>You\u2019re in the middle of a big project with tight deadlines. Parts of  your infrastructure are a little, well, jenky. Do you take the time to  make things cleaner and more coherent, or do you focus on coding, hoping  that your stack holds together until you have time to clean it up? Will  a new tool pay off or is it just a distraction from perhaps more  tedious, but more crucial work that needs to be done.<\/p>\n<p>This was my situation early this week when I started looking at our  deployment procedure when moving developing on our workstations to  making our work public on our webhost. I was working on a bug where  things that worked on our development machines weren\u2019t working on the  webhost. Instead of just setting up a new instance for testing on our  webhost, I decided to invest the time in exploring a new-to-me tool  called <a title=\"Fabric\" href=\"http:\/\/www.fabfile.org\/\">Fabric<\/a>.<\/p>\n<p>Fabric is a Python library and tool for scripting commands to be run  on a remote server over SSH. You can store it in the root of your Django  or other Python project and run tasks on the remote server. For  instance, to build up a new staging instance on our webserver, I type  \u2018fab staging mkinstance\u2019 on my shell. \u00a0In this example, <em>staging<\/em> and <em>mkinstance<\/em> are just tasks that you\u2019ve defined as Python functions.\u00a0<em>staging <\/em>is  a task that sets context variables about this particular instance, such  as the home directory where the other tasks will execute on the remote  server.\u00a0<em>mkinstance<\/em> just calls other tasks to create a new  virtualenv, install required Python packages, download the most recent  version of the source from git and more. I may go into the details of  our Fabric configuration in the future, but, more importantly, I want to  explain why I think exploring this tool to improve our deployment was a  good way to spend my time early this week.<\/p>\n<h3>Avoid <em>rm -rf .<\/em> \u201cOh #$%!(*&amp;!!\u201d<\/h3>\n<p>I would say that even savvy system administrators who know better,  who will lecture their junior admins about what not to do at great  length, sometimes hop in a shell to run a quick command only to  carelessly wreak disaster. I recently caught myself typing commands into  shells on the wrong host. There had to be a better way. Fabric modules  compel me to explicitly type the action that I intend to take and the  instance I want to take it on.\u00a0<em>fab staging destroyeverything<\/em> has a different resonance to ssh <em>somehost.com &amp;&amp; cd \/home\/ghing\/webapps\/ &amp;&amp; rm -rf myproject<\/em>.<\/p>\n<h3>A deployment reasoning tool<\/h3>\n<p>Automating your deployment process in a script helps you break down  the deployment process. What are the steps that need to be taken? What  order should they be run in? What are the dependencies between the  steps? Writing these things out in code helps identify redundancies or  potential problems in the process.<\/p>\n<h3>Code as documentation<\/h3>\n<p>An artist who taught game development to high school students told me  that she introduced students to the idea of programming by having them  work in pairs and take turns writing pseudocode to instruct their  partner about how to move around in a space. I\u2019d imagine one of the big  takeaways is the difference between code and natural language. The  latter can make for some beautiful journalism, but it can make  describing a process convoluted. After I finished our Fabric module, I  wondered how I would have written free form paragraphs to describe our  deploy process, or explain them out loud. Even with few comments, its  clear what\u2019s happening in the deploy process. In around the same time it  would take to write a step-by-step description of the process, I have  one in code that can also do all the steps for me.<\/p>\n<h3>Further Reading<\/h3>\n<p><a href=\"http:\/\/blog.apps.chicagotribune.com\/2010\/02\/10\/refactoring-fabric\/\">Refactoring fabfile.py for fast, robust Django\u00a0deployment<\/a> by Christopher Groskopf got me stoked about using Fabric, and it\u2019s a  good place to look for good practices for deploying Django in the cloud.  It was, however, a little daunting as an entry point to the different  tools.<\/p>\n<p><a href=\"http:\/\/www.clemesha.org\/blog\/modern-python-hacker-tools-virtualenv-fabric-pip\">Tools of the Modern Python Hacker: Virtualenv, Fabric and Pip<\/a> does a good job of describing the connection between these tools and how they can be successfully used together for deployment.<\/p>\n<p><a href=\"http:\/\/lethain.com\/entry\/2008\/nov\/04\/deploying-django-with-fabric\/\">Deploying Django with Fabric<\/a> helped get me started in writing my Fabric file and understanding the  conventions of the tool.\u00a0 Some of the information on this page may be a  little different with more recent versions of Fabric.<\/p>\n<p><a href=\"http:\/\/insatsu.us\/blogs\/thomas-schreiber\/deploying-djangos-sites-framework-webfaction-virtu\/\">Deploying with Django\u2019s Sites Framework on Webfaction (virtualenv, mod_wsgi, git) <\/a>helped me figure out some of the non-Fabric stuff to make deployment consistent on our webhost.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This was originally posted on the Local Fourth blog as part of my participation in a community media innovation project at the Medill School of Journalism. You\u2019re in the middle of a big project with tight deadlines. Parts of your infrastructure are a little, well, jenky. Do you take the time to make things cleaner&hellip; <a class=\"more-link\" href=\"http:\/\/blogs.terrorware.com\/geoff\/2010\/11\/05\/really-it%e2%80%99s-worth-it\/\">Continue reading <span class=\"screen-reader-text\">Really, It\u2019s Worth It<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[20589],"tags":[20594,20593,724],"class_list":["post-2213","post","type-post","status-publish","format-standard","hentry","category-medill-community-media-innovation-project","tag-deployment","tag-fabric","tag-python","entry"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4wnIz-zH","_links":{"self":[{"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/posts\/2213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/comments?post=2213"}],"version-history":[{"count":1,"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/posts\/2213\/revisions"}],"predecessor-version":[{"id":2214,"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/posts\/2213\/revisions\/2214"}],"wp:attachment":[{"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/media?parent=2213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/categories?post=2213"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blogs.terrorware.com\/geoff\/wp-json\/wp\/v2\/tags?post=2213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}