Archive for the ‘Subversion’ Category

Saturday, March 22nd, 2008

Ruby on Rails deployment is often regarded as a dark art. But the guys at Brightbox have made it simple with their Brightbox gem. I have recently moved three clients over - so I’m getting pretty good at deploying there. Here are the steps that I follow:

One:

Sign up with Brightbox and buy a box. You will need to know the account name, the ‘rails’ user password and the mysql password - all of which are available from the VM details page that is emailed to you. The brightbox will be provisioned with a name similar to “account-001.vm.brightbox.net”. I recommend ssh’ing into the box and changing the ‘rails’ user’s password - you will be typing it a lot - or installing your ssh keys.

Two:

Prepare your application in subversion.

You need to make sure that your config/database.yml file is included in your subversion repository (many developers prefer to leave it out for team reasons - don’t worry, you can take it out again later).

You should edit the production entry to point at your desired production database. Set the database name to account_database (where account is your Brightbox account name and database is whatever you want), set the user to your account name, the password to whatever you noted down above and the hostname to sqlreadwrite.brightbox.net (the Brightbox MySql cluster).

Don’t forget to set the svn:ignore property on your log and tmp folders.

Three:

Install the Brightbox gem on your development machine.

Use the brightbox command to generate the Capistrano file (telling it your application name, the name of your Brightbox and the desired domain name that your application will be running on).

At the same time, point your domain name (via an A record) at the Brightbox’s IP address and place a support ticket to set up a Reverse DNS entry (if you will be sending out emails). If you don’t have a domain name yet then use myapp.account-001.vm.brightbox.net.

Then open config/deploy.rb and edit the source code repository entry to point at your svn server (if necessary setting up scm_username and scm_password entries).

Four:

Run the cap setup command (if you have capistrano 2 installed, this becomes cap _1.4.1_ setup as, at the time of writing, the cap 2 version of the gem is still in beta). This will ssh into your server (so you will need that password) and set up the folder structure for you.

Then run the cap cold_deploy command. This tests whether things are working - as it tries to get your code out of svn and onto the server, sets up monit (to keep tabs on your app), uses the database.yml file to create a database and configures Apache with your domain name. If it fails you will need to edit your deploy.rb (and probably get rid of the created database so you can run it again).

You should see your application at your domain name. Stop a second and reflect on how much you have achieved :-).

Five:

Remove your database.yml from svn (set the svn:ignore property on it). Then copy it to the Brightbox (using scp) and place it in /home/rails/my_app/shared/ (where my_app is obviously your application’s name). If you have any file uploads (attachment_fu) or shared assets then copy them into the shared folder as well. Then edit your deploy.rb to add something similar to the following:



task :after_update_code do

  # link the relevant database.yml from the shared folder to the app's folder

  run "ln -nfs #{deploy_to}/#{shared_dir}/database.yml #{release_path}/config/database.yml"

  # link the file store to the application

  run "ln -nfs #{deploy_to}/#{shared_dir}/files #{release_path}/public/public"

end

This means that, after deployment, capistrano will create symlinks from your shared database.yml and shared files into your applications config and public folders respectively.

Six:

Try another deployment to test your symlinking. cap _1.4.1_ deploy - if all goes well then your application should still be running at your domain name, and monit will report that your processes are running correctly. From now on, all you need to do is commit to svn and then cap _1.4.1_ deploy.

Saturday, February 3rd, 2007

Have you ever used Microsoft Structured Storage? It is a COM API that allows access to ‘files and folders’ within a single file-system entity. For example, Word documents were structured storage - so all those embedded images and version history are stored as separate, accessible streams within a .DOC file. The API is actually quite easy once you get your head round it, but, like many COM APIs, it feels extremely complicated to use.

Apple (or more correctly NeXT) got around the same problem in a totally different way - using ‘bundles’. These are basically folders, not files. However, the (FTF)Finder treats them as a single file. Double click an RTFD file and it opens in TextEdit as if it were a normal document. Right-click and select ’show package contents’ and you see that it is actually a set of folders, with your text, embedded images and so on. And because bundles basically use standard file system semantics, there is no complex API to learn.

However, structure storage works nicely with version control - just treat it as a binary file. Bundles almost work nicely with version control. svn add document.lineform treats your Lineform file as a folder and then adds its contents in the same way as any other folder.

I quite happily added a load of documents into subversion the other day and then made the mistake of moving them in the Finder. I successfully removed the old location from the repository. But whenever I tried to add the “new” copy I would get ‘document.lineform is already under version control’. Yet a status command showed a question mark - meaning that the file needed adding.

It took me a while to figure it out, but eventually I got there. When you use subversion it creates a hidden .svn folder inside every folder. This creates all the status files - details of modifications, the original version and so on. And as bundles are treated by subversion as folders, they get these invisible folders as well. So when I moved my ‘file’ it copied these hidden folders as well. Hence subversion thought my file had already been added - it had subversion’s fingerprints all over it.

The solution? A quick rm -R -f document.lineform/.svn wipes out the hidden folder and we are back to normal.