Leveraging Drush Aliases in Your Drupal Deployment Workflow

Along with git, drush ― [Dru]pal [Sh]ell ― aliases are an extremely useful, and powerful tool when dealing with a drupal dev-stage-production workflow.

The idea is simple: create an alias for your different environments, allowing you to perform drush tasks on remote servers. Included is additional functionality such as syncing files, databases, or using any other drush command - even the usual drush cc all et al.

There are a couple of ways to define aliases. One of them is to place the alias file in a sites/*/drush directory. However, the option we're going to go over is defining them in the ~/.drush directory.

The reason I prefer this method is that it means doing all of the drush tasks on my development environment, while keeping any other environments clean. Further, as my development environment is on a localhost, it's generally not publicly accessible.

If you haven't already, the first thing to do is add an SSH key so passwords aren't required each time. You can take a look at this article, but here's the gist:

  • On your localhost: ssh keygen -t rsa,
  • Enter x3,
  • Copy the ~/.ssh/id_rsa.pub key,
  • On your remote host, add it to ~/.ssh/authorized_keys (or create the file if it doesn't exist),
  • That's it. You can now SSH to your remote host without a password.

Back to drush. What we need to do is create an alias for each environment in our workflow for a given project. Let's call the project mysite.

As mentioned, drush will look for your alias definitions in a few places, one of them being ~/.drush. It searches for files in the directory ending with *.aliases.drushrc.php.

When calling an alias, the syntax is drush @aliasname.environment COMMAND. Since we're creating an alias for mysite, create the file: vi ~/.drush/mysite.aliases.drushrc.php.

The file contents are in the format of a nested PHP array called $aliases, and each top-level key corresponds to one of your environments.

Lets suppose we want 3 environments: dev (local), stage, and prod. The skeleton for the mysite.aliases.drushrc.php would be as follows:

Creating Drush Aliases

<?php

  // Define the development environment.
  $aliases['dev'] = array(

  );

  // Define the staging environment.
  $aliases['stage'] = array(

  );

  // Define the production environment.
  $aliases['prod'] = array(

  );

There are a few keys that will be present in every definition, let's start with dev as it's the simplest. As mentioned, my development environment is on a localhost. If you plan to use the first option mentioned and would like to run commands from your stage/prod environment to dev, you'll want to skip this and do the same thing as the stage/prod environments below.

<?php

  // Define the development environment.
  $aliases['dev'] = array(

    // The path to your drupal base.
    'root' => '/Users/skh/Dropbox/Private/Sites/mysite',

    // The development URL.
    'uri'  => 'mysite.dev.e9p.net',

    // Path aliases to common directories.
    'path-aliases' => array(

      // Where to dump temporary files.
      '%dump-dir' => '/tmp',

      // The path to our default's directory.
      '%default' => 'sites/default',

      // Options for specific commands.
      'command-specific' => array (

        // When running 'drush sql-sync'.
        'sql-sync' => array (

          // Setting simulate to 1 is the equivalent of doing a dry-run.  This becomes more useful in the prod alias below.
          'simulate' => '0',
        ),
      ),
    ),
  );

The above is heavily commented, but be sure to replace the values with your requirements. We don't need to define other values since drush will take the remaining settings from your settings.php.

Moving on to the remaining aliases, we need to define additional values such as the SSH and DB credentials. Here's how:

<?php

  // Define the staging environment.
  $aliases['stage'] = array(

    // Setting a parent will inherit all the values, unless explicitly overridden below.
    'parent' => '@local',

    // The path to your drupal base.
    'root' => '/var/www/html/mysite.net',

    // The staging URL.
    'uri' => 'stage.mysite.net',

    // The staging box hostname.
    'remote-host' => 'stage.e9p.net',

    // The user your would use to connect to the box by SSH.  Since we setup SSH keys, no passwords will be necessary.
    'remote-user' => 'skh',

    // Any additional SSH options, such as specifying a specific port.
    'ssh-options' => '-p 2046',

    // Allow unknown options to proceed and warn rather than fail.
    'strict' => 0,

    // Define the staging databases.  Take this from your settings.php file on the stage box.
    'databases' => array (
      'default' =>
      array (
        'default' =>
        array (
          'database' => 'mysite_v1',
          'username' => 'mysite',
          'password' => 'mysite_localhost',
          'host' => 'localhost',
          'port' => '',
          'driver' => 'mysql',
          'prefix' => '',
        ),
      ),
    ),
  );

The only real point of note from the above: since drush will execute this command via SSH on the remote box, we can just use the normal localhost SQL credentials. Further, you most likely shouldn't be allowing SQL access outside of your environment, unless you've done something like splitting the database and code into different servers on the same local network.

Finally, the production environment will be identical for above, with one small (but important) change.

If you remember, in the dev alias we set simulate => 0, and the stage environment inherited that value. This allows us to overwrite both dev and stage databases with the sql-sync command (as described shortly).

The chances are you likely don't want to be able to overwrite your production environment's database. For $aliases['prod'], copy the stage alias with the necessary changes, and add:

<?php
  $aliases['prod'] = array(
    ...
    'command-specific' => array (
      'sql-sync' => array (
        'simulate' => '1',
      ),
    ),
    ...
  );

If you like, the full file can be downloaded at the bottom of the post.

Now... on to the fun stuff!

Using Drush Aliases

The hard part is done. Here's some of the powerful tasks you can automate with drush aliases. Be sure to check out the links at the bottom of the post for more.

  • Sync the database from your staging environment to local:
    • drush sql-sync @mysite.stage @mysite.dev
  • Sync the files directory from production to development:
    • drush sql-sync @mysite.prod @mysite.dev
  • Backup your entire production install (files & db). Great for the initial transition between environments:
    • drush archive-dump @mysite.prod --destination=example.tgz
  • Restore that backup to your development environment:
    • drush archive-restore example.tgz
  • Sync the sites/default directory on prod to dev via the created path-alias:
    • drush rsync @mysite.prod:%default @mysite.dev:%files
  • Clear the cache on the remote staging environment from development:
    • drush @mysite.stage cc all

This is just a sample of the power and usefulness of drush aliases. Be sure to check out the drush homepage below for more.

You can repeat this process as many projects as you like by creating more sitename.aliases.drushrc.php files in your ~/.drush directory.

Useful links


AttachmentSize
Plain text icon mysite.aliases.drushrc.php3.5 KB

Comments

T. Mansveld's picture

T. Mansveld

In your Drush use cases, the second bullet point is a direct copy of the first (obviously, sql-sync is not the command for syncing files). And second, the referer to the parent should be @dev and not @parent (incorrect copy/paste I assume ;)).

Besides these points, this is a very good and clear explanation. Better then most other!