Simple Deployment using Git (or Mercurial) and DropBox
- Saturday, January 29, 2011
You would think that someone would have tried this before - but I haven't seen anyone blog on it yet. I'm sure I'm not the only knuckle-dragging mouth-breather who eschews High Concept for Dumb-simple solutions when available. Today I think I might have broken my own record for ugly: I deployed a site using Git and Dropbox. And I love it.
This Could Explode
You've been warned. I won't take responsibility for the corrosion of your soul or that black sticky stuff that oozes from your eyes once you see the code I'm about to write. It's fantastically simple and elegant. It's intellectually bankrupt and capricious. It's perfectly, deliciously horrendous.
I have yet to find a reason why this isn't the perfect solution to the nightmare that is deployment to IIS when you don't want to feed at the trough. Perhaps you will tell me. Then again your head might explode in the next 5 minutes.
If you're using Apache or Nginx on Ubuntu this will work as well. However the need generally isn't as great with *nix machines because of SSH and little lovelies like Capistrano. But read on anyway - you might find some simplicity here.
Step 1: Install DropBox
You'll need to do this on your dev box as well as your server. Yes. Your server. If you don't want to - kick up a VM or maybe spin one up for a bit at Amazon. This solution won't work unless you have full frontal access to your server.
You might have heard of Dropbox. It's cloud-based file storage. I have a lot of code/pictures to write here so I'll simply suggest that if you don't have Dropbox - go sign up. It's free, and it's great for archiving your stuff. There's premium packages that are incredibly cheap that offer extra storage - but for our purposes we can use a free plan.
Another question you might have: how secure is DropBox? From their FAQ:
We use the same secure methods as banks and the military to send and store your data.
Dropbox takes the security of your files and of our software very seriously. We use the best tools and engineering practices available to build our software, and we have smart people making sure that Dropbox remains secure. Your files are backed-up, stored securely, and password-protected.
< snip >
Dropbox uses modern encryption methods to both transfer and store your data.
Shared folders are viewable only by people you invite ... All transmission of file data and metadata occurs over an encrypted channel (SSL). All files stored on Dropbox servers are encrypted (AES-256) and are inaccessible without your account password
Sending/Receving files online always involves some kind of risk, but it's safe to say that Dropbox is probably more secure than what you're using now. You also get a free backup of your site should your server explode.
Step 2 (Optional): Install Git or Mercurial
This only needs to happen on your dev box. The only reason we're doing this is because you get to push your repo to DropBox (and your server) - which allows you to revert your site should you screw up. More on that later.
If you haven't used Git or Mercurial then now's the time.
Step 3: Set Up Your Dev Box
Now that you have DropBox and Git installed - we need to create our site. You can create it wherever you like - but you do not want your dev site to be located in DropBox. That's only for deployment and Git will take care of the versioning. I'm going to use WebMatrix (surprise) and create a Photo Gallery from a Template:
Next, I'll initialize a Git repo here. If you don't know what Git is or how to use it - there's a lot of help online including this stellar screencast series.
Right-click your project, select "Show in Windows Explorer". Go one directory up (in my case the folder is called RobsPhotos.com), right click again and select "Git bash here." Once the shell opens - type in "git init". This creates a repo for you.
The next step is to add a filter file - telling Git what we don't want it to track. There are a number of things - project files, solution files, obj/bin etc. You likely have a filter file - I like this one (which I stole from Derek Bailey):
obj bin *.csproj.user *ReSharper* *resharper* *.suo *.cache Thumbs.db *.bak *.cache *.log *.swp *.user _compareTemp _notes aspnet_client httpd.parse.errors
In your Git bash terminal type "touch .gitignore" - this will drop a .gitignore file in which we need to paste the above text. So, type in "write .gitignore" and up pops WordPad - paste the code above in there and you're good.
Now we need to commit:
git add . git commit -am "Initial Commit"
You should see some text flying by - that means we're excited. If you're an Hg user then you know what to do here. Just about the same exact thing.
Step 4: Setup The Deployment
Now you need to head over to your Dropbox folder. Open File Explorer in Windows (or the Finder on your Mac) and you should see a link to your Dropbox folder. If you've just installed it - it's empty. Open up the directory - in here is where we want to put a directory for our live site.
I've created a directory called "WekeRoad" (where I'm going to host my site - my IIS box). Call it whatever you like - the idea here is that I want to have a directory for all kinds of deployments to my WekeRoad box. Your strategy could be whatever you like.
Inside here I want to pull a clone of my project. So I right-click on my WekeRoad directory and once again "Git bash here". This pops the Git shell, putting me in the Dropbox/WekeRoad directory:
You might be wondering: Why don't you just push your repo?
The answer is that this will just push the changes to the .git repo - it won't drop the files. That's what I need: the files, not necessarily the git repo (though I want that as well). Once the clone goes off, DropBox does it's thing:
All the files have been cloned into my local DropBox directory, which will automatically sync all the files to the cloud when they're changed. Inside that directory, thanks to my .gitignore file, are the only files my live server is going to care about:
That's it for my dev box. If you're a Git person you've probably figured out what to do from here - but hang tight I have some additional thoughts at the end. Right now let's transition to the server.
Step 5: Set Up Your Server
This isn't just a "click and run" installation - there are some considerations. First - I'd highly recommend that you dedicate an entire DropBox account to your project. This will allow you to not only push your site, but all documents, SQL files, and other stuff securely into the cloud.
This is up to you - but should you ever leave the project you can easily hand over the account to someone else. Just keep it in mind.
When you install DropBox it will want to locate your documents on C:\Dropbox. Set this somewhere (obviously) that makes sense to you. The installation will proceed and then ask you to login with your user/password. Do that and it will then ask you if you want to sync all directories or just the ones you select.
You don't want all your files pushed to your server (unless you don't care). Instead - select the ones you want sent up:
In my case - the only directory I want is my "WekeRoad" directory. This is an important consideration - when you share directories in DropBox with other DropBox users (a great way to collaborate which I'll talk more on in just a bit) - you can only do so from the root. So name this carefully and understand that when you share - you'll share everything under it.
In my case I'm going to pull down my WekeRoad directory to my server - once I do, it takes about 1 minute for a groovy little present to appear:
And that's it. I'm deployed. That was pretty painless - all I need to do to deploy my site is a "git pull origin master" from my local DropBox and it will get pushed to my server. It sort of makes me feel a bit guilty and ... dare I say just a little bit dirty.
The Benefit of a Git Repo On Your Server
A lot of people might look at this and say "duuuuude you don't want your repo on your server!". I can understand that. Not really - why is that again? I can actually think of a LOT of reasons why you WOULD want this - namely rolling your deployment back and also knowing precisely who pushed what, when.
First things first - make sure you have RequestFiltering enabled on IIS - and then block access to .git. You can also do this from the Web.config:
< configuration > < system.webServer > < security > < requestFiltering > < hiddenSegments > < add segment=".git" / > < /hiddenSegments > < /requestFiltering > < /security > < /system.webServer > < /configuration >
Do you screw up? I do. I don't like it, but I do it from time to time. One of the things I dig about Capistrano is "cap deploy:rollback". When James completely blows up our site, I can roll it back quickly and we're generally good to go. This is critical when working with a scripted thingy like WebMatrix.
A lot of .NET developers rely a bit too much on their compiler to catch their errors. WebMatrix removes that safety net - and this means things can blow up.
Using DropBox and Git together, this becomes as simple as
git reset --hard [COMMIT ID]
BAM - your working directory (which is your live site) is immediately synced up with Dropbox and pushed live. Oh the joy!
It Goes Both Ways
One thing that's a major PITA is figuring out when things go wrong. DropBox can make this a hell of a lot easier - check it out:
This will synch whenever the log file is updated. You now have full access to your server logs, synced right up to whatever machine you need.
DropBox Sharing and Workflow
You can share your DropBox directories with other Dropbox users - giving them access as needed. Ideally you don't want just anyone deploying to your server (if you're on a team) - so you can restrict that directory to yourself if you like, or someone you trust.
How you setup and share your directories is of course, up to you. Some things to remember, however:
- Sharing means full read/write access. Make sure that when you share people know this - and that deleting a file means it's gone from everyone's machine.
- Dropbox works great for simple sync's - but it's probably not the best option to hold your Repository Hub. I haven't tried it - but I can imagine a collision that corrupts it easily. You're better off using Github or something - sand setting up your DB deploy directory to pull from there.
- You can have more than one DropBox account. Consider having one per project and setting up your project folders under that account. Then you can share out various project folders as needed. Or better yet - just use Unfuddle/Basecamp as that's why they're there.
You probably should be. But WebMatrix's publishing bits are "just OK" given the IIS setup craziness for WebDeploy (with the only other option being the Neanderthal FTP push).
DropBox and WebMatrix seem to fit together like bubblegum and popcorn. It would even work for MVC and "bigger" .NET web projects - but I'm sure that it's much easier to use CruiseControl or TeamCity pushing to an FTP destination using an MSBuild post-build hook :p.