This is Part II. Read Part I.
As I mentioned earlier, Siskiwit and Rosco were unintentional BFF. When I launched Rosco I wanted to preserve the link structure of Siskiwit, because people were still way into searchin’ for and diggin’ on that stuff.
Siskiwit had a long and colorful history of publishing platforms, but a number of years ago it settled on Movable Type, where it has remained ever since. Recently I tried upgrading its circa-2005 installation to the latest and freshest version, Movable Type 4.1, and I nearly fell out of my chair because it executed so flawlessly. Seriously, nothing went wrong. This made me realize that Siskiwit was far more portable than I gave it credit for, and I began strategizing on how to move it away from brainsideout.com/weblog and onto its own subdomain.
Up until recently, I have done all of my development on my server at DreamHost, hosting them at super-secret subdomains. The majority of my development cycle would involve launching Transmit, opening a file on the server in TextMate (or BBEdit if I need to do some heavy-duty regex), editing that file, saving it, and refreshing my browser window. I don’t know how many web designers work this way, but I’m willing to bet a fair amount of them.
If I’m installing a package of software (say, Movable Type or WordPress) I’ll often FTP into my server to upload the tarball or .zip file, SSH into my server to expand the file, and then return to Transmit to move the expanded folders and files to their proper locations. Ditto for large image directories, or other cases where I have multiple files to upload at once. All the goddamn handshaking that goes on with an FTP transfer makes it a horrible tool for uploading multiple files, and if your connection drops halfway through a transfer, it’s difficult to figure out what got copied successfully and what didn’t. I don’t know how many times I’ve been hosed by a file that appears to have transferred successfully, but turns out later to have been only a 0 KB placeholder.
This, this development process is dumb. I never realized how dumb until I started working with Jason, and we did all of our development in Subversion.
Subversion: Time Machine for Your Project
If you’ve never used a version control system you may have no idea what all the fuss is about. Once you’ve used one, though… no, once you’ve lived in one for a few weeks, you’ll wonder why everything in the world isn’t done this way. Seriously, everywhere I look now I see opportunities for version control. I wish I could rollback the street in front of my house, so I could drive on it at a moderate speed without bottoming out on this year’s crop of potholes. I wish I could form a branch for this day, which has been kind of cloudy and crummy but altogether windy, and see what would have happened if I chose to go kiteboarding instead of writing all afternoon. The planet? Sheesh, talk about something that needs to be loaded into Subversion, like, yesterday.
Subversion is a popular open-source version control system, which stores and tracks every change made to every folder and file that you load into it. Well, not every change, as it only tracks changes that you “commit” to it. Anywho, it’s like Time Machine for code. Your entire Time Machine drive would be called a “repository” in Subversion parlance, and every snapshot of your computer (or project) at a particular moment in time would be considered a “revision”.
Phew! Being a noob myself I’m in no place to teach you everything you need to know about version control with Subversion, but fortunately there’s an excellent book on that very subject. If nothing else you should read chapter one, which covers the fundamental concepts of version control, and shows some examples of Subversion in action.
If you’re used to developing on a web server, applying version control to your development requires a fundamental shift in practice. Fortunately, this shift is one that turns out to be rewarding in many ways, including speed of development, robustness of your code, and ease of deployability. Your Subversion repository lives in the cloud, so to speak, and you download, or “checkout”, the most recent revision to a folder on your local machine to do your work.
OS X Leopard has just about everything you could ever want in a web server already installed on it, including Subversion, Apache 2, mod_rewrite, PHP 5, Ruby, Ruby on Rails, and MySQL, so creating a local web development environment is a pretty straightforward deal. That said, a lot of these fixin’s aren’t enabled out of the box, and they will take a bit of mucking around to get running. You need to turn on mod_rewrite and PHP, you might want to upgrade Rails and other preinstalled Gems, and installing the MySQL preference pane might make your life easier. At a later date I’ll try to outline my experience of getting my own OS X development environment running. For now, just trust me.
A step-by-step manual for setting up your local machine for version-controlled development is outside the scope of this article, but at the very least I want to give you a cursory glance of what my current setup looks like. This all came into being within the last few weeks, but already it hands-down beats the knickers off Ghetto-Ass Subdomain Remote Web Server FTP Development.
Non-Ghetto-Ass Local Development
First off, if you need a Subversion repository look no further than Beanstalk, who definitely put the sexy in version control. Honestly, if my first time had been with anyone but Beanstalk, I would have sworn off the whole thing entirely, given the craptastic nature of most Subversion applications. Most host and client setups assume prior knowledge of Subversion, incredible technical aptitude, and hella-tolerance for lousiness. Beanstalk makes it really easy to import your initial project into Subversion, and offers a free account with up to 20 MB of space, which will be fine out of the gate unless you’re planning on working with tons of images. Or, perhaps, if you’re planning on using the SQL on Rails framework.
The cool thing with Subversion is that every time you commit a revision to your project, it doesn’t need to make new copies of all the files. It hardly even makes a copy of the updated files. Nay, it just tracks and records the changes within the files. Thus, a 2 MB project with 10 revisions will not weigh 20 MB. For instance, I have a current project where my working copy weighs 11.5 MB, but the repository (with 69 revisions already) only weighs 3.4 MB. Wow, that’s a surprise. I have no idea how that works, in that my working copy weighs more than the entire repository. Perhaps there’s some voodoo magic going on, but I’m not gonna argue!
Once you have a repository, you’ll probably want to install a Subversion client on your local machine to make it easier to interact with the repository. Subversion is built with the command-line in mind, but a lot of us don’t think that way. I’ve been using the svnX client for a number of months now, and while it’s incredibly goofy I believe it’s the best one available for OS X. You can configure it to connect to a repository, and then checkout a revision to make a working copy on your local machine.
Managing, hosting and testing multiple web design projects can be a pain, however, especially if you don’t want to muck around inside Apache’s httd.conf
file. I use Headdress, a tiny application that helps you manage virtual hosts in OS X, to handle all of my local development websites. The free version of Headdress lets you host two sites simultaneously, and if you want to run more it’s a lousy $14.99.
Ahem. Welcome to your new workflow, where you edit your local working copy while testing it in a browser window. When you feel like you’ve reached a comfortable point in your development, or if you’re about to try something risky, go ahead and commit the changes you’ve made to your working copy to the repository. This is how I do it now. Edit locally, refresh locally. Edit locally, refresh locally. Time to fix another cup of tea? Commit all local changes to the repository as a new revision.
“What about launching? What about deploying? What good is all this work if no one can see it?” I’m glad you asked! I still maintain a number of super-secret subdomains, where I can test my development work directly on the web server that will ultimately host its production version. Remember, the working copy of your website on your local machine is just that: a copy from the repository. So long as you’ve committed all your changes, the exact same site exists inside the repository as the most recent revision of your project.
Deploying your site, whether it’s deploying on a testing domain or deploying for realz realz, is just a matter of “checking out” a fresh copy from the repository. This is pretty easy, so long as you have Subversion installed on your web server. I’ve found the easiest way to do this is to SSH into my server, navigate to the parent directory that holds the folder in which I would like to expand the copy, and using the svn checkout
command to checkout the most recent revision from the repository into that folder. After I’ve done that, I can continue to freely edit my working copy on my local machine, and commit those changes to the repository, without worrying about messing up the copy on my web server.
Once I’m happy with some new changes I’ve made, however, it’s easy to bring the version on my web server up to speed. All I do is SSH into my server, navigate to the child directory into which I originally checked out the copy, and type svn update
. Bam! Everything that was out-of-date is now up-to-date! It can certainly be a lot more complicated than this, which is why there are services like Capistrano that automate the deployment and updating process, but at its most basic this is what’s going on.
“Dammit, Dane!” you’re saying. “What about my database? What about my needs?” Indeed, to make this work well you need to have a database that your local working copy can connect to. Sometimes you can use a remote server, which is what I did until I found a better solution. Currently I run a few MySQL databases on my local OS X machine, which I connect to via localhost
and manage through CocoaMySQL. Getting WordPress to connect to a local MySQL database took a bit of finagling, but a quick search revealed an easy solution.
Disentangling Siskiwit
So. I wanted to move Siskiwit, and each and every part of it, out of Brainside Out and onto its own domain. The fact that I was able to upgrade Movable Type made me realize that Siskiwit was likely more flexible and portable that I had thought. To test this theory, I created a new project on my local machine, did a fresh install of Movable Type on it, and imported its current MySQL database onto my local MySQL server.
After changing a few configuration files to reference the new local database, I told Movable Type to rebuild all the weblogs, which it did flawlessly after only a few initial hiccups. I had a few stray layout, design and container files that I had to bring down from the live server, but the amount of customization necessary to get the site working was minimal.
At this point, the old skool way of doing things would have been to wrap up my local copy of the site in a zip file, FTP it to its corresponding subdomain on the server, and SSH in and expand the file. As if! Instead I created a new Subversion project at Beanstalk and imported my local copy of Siskiwit as a starting revision. From there I SSH’d into my server and ran svn checkout
to put a copy at its new subdomain. I changed a few configuration options to make the site reference its live MySQL server, had it rebuild all the weblog files, and it all worked like gravy.
It’s worth noting that I left all the “rebuilt” weblog files out of the Subversion repository, and I left out the actual Movable Type install as well. With the former, Movable Type creates the static rebuilt files based on the content in the database, so they’re completely unnecessary so long as Movable Type has a database to work with and rebuild from. With the latter, since I’m never going to edit the Movable Type system files there’s no need to keep them under version control, so I just uploaded the .zip to the server and expanded it.
Likewise, since my images directory for Siskiwit is pretty huge, and since I don’t plan on making any changes to it, I left it out of the repository as well. This can be some fairly subtle and complicated stuff, and I mention it just to be clear that it doesn’t make sense, nor is it necessarily advantageous, to store everything in version control. Your own mileage may vary.
Before nuking every last trace of Siskiwit from Brainside Out, I wanted to make sure that visitors accessing pages at their old locations (either through search engines or through a crazy-good memory) would be seamlessly redirected to the page’s new location at the site’s new subdomain. I did this by adding the following rule to my .htaccess
file in the root of brainsideout.com:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?brainsideout\.com$
RewriteCond %{REQUEST_URI} ^(/weblog|/photolog|/sundries|/classics|/av)
RewriteRule (.*) http://siskiwit.brainsideout.com/$1 [R=Permanent]
I have a few more rules besides this one, but they relate to CodeIgniter and aren’t relevant here. Also, if you want to monkey with .htaccess files on your locally hosted OS X websites you’re going to have to turn on mod_rewrite. It’s a bit of a thing, but you probably won’t die trying to do it. Headdress does have a bad habit of occasionally overwriting changes that you’ve manually implemented in your httpd.conf
, especially when you add or remove a site from within Headdress. Yeah. Good luck with that.
With Siskiwit under version control and relocated to its new subdomain, and Rosco versioned and backed up as well for some inexplicable reason, I was finally ready to nuke everything at brainsideout.com and deploy the new, CodeIgnited version. I SSH’d into the server, navigated to the corresponding directory, and with cautious fingers typed rm -Rv --preserve-root *
.
I then left my computer and fixed myself a drink. Upon returning I checked, double-checked and triple-checked my work, and pressed return. Then, with a haste matched only by the files scurrying up my screen, I deployed the new edition of Brainside Out from the repository.
Spring is here, and comments are open.
That’s right, comments. It’s gonna be that kind of spring.
End Part II. Read Part I.
5 Comments
Good golly. I quit playing the design game for a few years, and look back to find you a thriving expert. Damn fine run you’ve made, sir.
All the best to you and Kate from the Antarctic wastes…
I’ll catch you in the fall.
Ahh shucks, thanks Nate! It’s awesome to hear from you, and I hope the South Pole is treating you well. That’s a beautiful picture you’ve posted there on the tomes.
Indeed, we look forward to catching up with you this fall. Stay warm, stay sane, and stay safe. No fair giving yourself scurvy on purpose!
Dane, you insane, fellow Minnesota ex-pat… you’re up to great stuff as usual. You scare me. ;-)
I noticed you’re using the Headdress… tried MAMP? It’s free, drops right into your Applications folder (you don’t have to muck with command line stuff), and has been bullet-proof for me. I love, love, love it.
Also, have you tried the TextMate SVN bundle? It makes life a little simpler. And this new Versions app? Well that’s just scary, like Dane.
Now then, I must try out some of these mad tips of yours. Groove on.
Heh, thanks Steve! I’ve been moving away from software packages and trying to make use of the native features of the operating system, but based on your recommendation I might have to give MAMP a shot. Drag and drop sounds pretty enticing, especially after all the little nooks and crannies I had to explore to get my current environment tweaked just right.
The TextMate SVN bundle is pretty handy, but I found that I needed something more visual, with a bit more guidance, than that.
In my most current workflow, svnX has been canceled. Versions is, to put it bluntly, the shit.
Hey Dane, just found something else to make life pleasant. If you’re testing your stuff on localhost:8888 and want to see how great it looks in IE via a virtual Windows environ (such as Bootcamp, VMWare, Parallels), try the following:
* open that Window’s host file C:\WINDOWS\system32\drivers\etc\hosts
* look for the “127.0.0.1 localhost” line
* add your Mac’s active IP and fancy host name to the next line (e.g., 192.168.2.2 mamp) and save
* fire up IE and go to http://mamp:8888/ (you’ll need the http:// part in IE) and you’re in bidness!