Wednesday, September 14, 2011

Drupal SVN Deployment Strategy

Drupal SVN Deployment Strategy

Submitted by Jay on Mon, 08/23/2010 - 13:15
In the past year, I have started using SVN to deploy my Drupal installations. In the following post I will discuss my own personal SVN deployment strategy. This strategy allows me to work locally on a WAMP installation, and use SVN to deploy my sites to their remote installations.

Disclaimer: By no means am I claiming this is the only way, or the best way to use SVN in conjunction with Drupal. But, it is a method that works well for me, and I thought I would share it with others. If anyone has any comments on how they deploy Drupal themselves, or possible ways I could improve my own deployment strategy, I would love to hear them.

I work on a number of different Drupal installations. I maintain my own site, as well as a number of client sites. In deciding my deployment strategy, I considered the following points:

Drupal will be the same across all installations
The modules and themes (for the most part) will be different in each installation.
I don't want to use SVN for the sites/default/files folder, as the contents of this folder are generally user generated, and should be backed up using other methods
I need a way to deploy database backups and keep them for future reference
There are some situations where I have altered Drupal core. Most people think that this is an absolute no-no, but rather, the rule of thumb should be 'Don't alter Drupal core unless you know what you are doing'
In considering the above points, I decided on the following strategy. First, I need one central repository for Drupal core. This repository has to contain Drupal core, along with any alterations I have made to Drupal core (such as allowing for unlimited uploads per user by role in the upload module - a feature currently available). Every time I create a new site, I simply check out my core files into the new installation directory on the server where the new site will reside.


In putting together this strategy, I did the following:

I created a Drupal installation on my local PC.
I then made my core alterations, and imported it into the central repository, which is on my own server that I maintain.
I then checked it back out of that respository onto my local PC. This allows me to make future alterations and just check them in if necessary. Note: to preserve my core alterations, I use a technique called Vendor Branching. Explaining how this works is more than I can go into in this posting, but it is explained very well, with a screencast, on You can see the screencast here: Drupal Vendor Branching
When creating a new site, be it local on my machine or on a remote server (usually both, since I initially do my development locally and then deploy the site to the remote server), I simply check do an SVN checkout, which automatically checks out the files into the new directory. The advantage of this is that anytime a new version of Drupal comes out, all I need to do is update the local repository, then navigate to the root directory of each of my Drupal installations and run svn update. This automatically updates the relevant files on each installation, and only takes a few seconds per installation. If necessary I run the update.php script, and the site is updated. I can literally update multiple sites in minutes, whereas it used to take hours, between downloading core, going through and checking all my core modifications in the new files, logging into each installation separately and uploading the entire core through FTP
So that takes care of the common file system (Drupal core) through all of my installations. Next is my deployment strategy for the 'all' folder (modules and themes) in each installation. For the most part, this will be different between each installation. There are some modules that are common to all installations, but I generally just add them to each installation as it is not really a big deal. My 'all' folder looks like this:


In working with this, I do the following:

Log into my server and create a new repository for the site in question
Start building the site on my local PC
After doing some work, I import my local 'all' folder into the respository
Check out the repository into my local 'all folder'
Log into the remote Drupal installation (the remote site), and create an 'all' folder in the 'sites' directory
Check out the repository into the remote all folder
Do more work on my local installation. At intervals, I commit my work to the central repository.
Log into the remote installation, navigate to the 'all' folder, and run svn udpate. This grabs all the newest code and updates the folder to the most current version of the modules and themes
Through the above two steps, I have now created a remote Drupal installation and a remote 'all' folder. This covers core, non-core modules, and non-core themes. All are versioned, and all are easily updatable after work done on my local installation. However, there are two more areas which need to be considered, the database, and the sites/default/files directory. As I build individual pages on my local installation through the admin interface, these are only stored in the database. The same goes for any other changes made through the admin interface. As such, I need a way to sync my databases between the installations. I have found the Backup and Migrate module to be excellent for this. It is made specifically for backing up Drupal installations and is one of the modules I install on every single site I create. I also create a respository for my database backups made through this module.


To manage database backups, I do the following:

Log into my server and create a new 'db_backups' repository for the site in question
Enable the backup and migrate module on my local PC.
Navigate to Administer -> Content management -> Backup and Migrate -> Destinations (admin/content/backup_migrate/destination), and create a new destination called 'remote'. This destination won't actually be used on the local PC, but since the database is synced between the local installation and remote installation, I need to create the destination here or it will be overwritten each time I re-sync the databases. Note: all destinations, 'manual', 'scheduled' and 'remote', should ideally be placed outside your webroot so as to increase security
Navigate to Administer -> Content management -> Backup and Migrate (admin/content/backup_migrate), and do a quick backup to the manual backups directory
Do an SVN import of the contents of the Backup and Migrate 'manual' directory to the 'db_backups' repository on my server
Do an SVN checkout of the 'db_backups' respository into the Backup and Migrate 'manual' directory
Log into the remote Drupal installation (and install it if I haven't already)
Enable the Backup and Migrate module
Navigate to Administer -> Content management -> Backup and Migrate -> Destinations (admin/content/backup_migrate/destination), and create a new destination called 'remote'. This remote directory WILL be used on the remote installation. This destination should also be placed outside the web root so as to increase security
Do an SVN checkout of the 'db_backups' repository to the 'remote' directory on the remote installation
On the remote installation, Navigate to Administer -> Content management -> Backup and Migrate -> Destinations (admin/content/backup_migrate/destination), and click on 'list files' for the 'remote' destionation
The quick backup that was taken on my local installation should now be visible on this page, as it was checked into the respository and then checked out into the remote folder. Click 'restore' for this backup. This will take you to another page where you click the 'restore' button. This will install the database backup into the remote installation, syncing it with the database on the local installation
As necessary, take a quick backup of the local installation, commit it to the repository, update the contents of the remote folder, and restore the new backup
Once the site goes live, the db_backups repository can be deleted, as the local installation will never contain the same code as the remote installation. However, this repository *could* be used as an external backup for any database backups taken on the remote installation.
And that just leaves the contents of the sites/default/files folder. I generally just upload these through FTP, as there is no real need for versioning of these files, and generally when I am creating a site, this folder is barely even used, as it is mainly files created through the admin interface.

So that is my Drupal SVN deployment strategy. I'm interested in hearing any ideas on how this can be improved, as by no means am I a pro, and/or hearing how other people use SVN with Drupal in order to facilitate a smooth workflow.


No comments: