Type less and do more with Drush Site Aliases

At this point in the book, you may have already executed quite a few commands. Some of them need a long list of attributes and options in order to behave as your needs demand. Plus, you always have to take care of being at the root of your Drupal site. Moreover, if you use named sites in your sites folder instead of using the sites/default directory, you always have to add the --uri option or execute commands from the settings.php path. This is annoying and makes command typing tiresome and prone to error.

Enter Drush Site Aliases. A site alias is a short name that defines several options about a local or remote Drupal site such as where it is located, what is the username, host to log in via SSH, which sites has it defined at its sites directory, and many more. Think of it as an array with options.

We will first explain what are the benefits of setting up local site aliases, and then go one step further and start invoking Drush commands to Drupal sites located in other systems through remote site aliases.

Configuring a Local Alias

We will start by defining a site alias for our Drupal testing site and try a few commands with it. Create the file drupal.alias.drushrc.php within your .drush directory with the following contents:

<?php
/**
* @file
* Site alias for local site called "Drupal"
*/
$aliases['drupal'] = array(
// Set here the path to the root of your Drupal installation.
'root' => '/home/juampy/projects/drupal/',
// Here goes the URL of your site.
'uri' => 'drupal.localhost',
);

As you can see in the previous given code, we are defining an array $aliases (respect this variable name so Drush can discover the alias) that defines a site alias called drupal with the following options:

  • root: the root path of our Drupal site.
  • uri: the URL of our site. This will be used as a --uri option with each command being executed.

Now let's see how to use our brand new site alias with some Drush commands:

$ drush site-alias
@drupal
$ drush @drupal status
Drupal version : 7.10
Site URI : drupal.localhost
Database driver : mysql
Database hostname : localhost
Database username : root
Database name : drupal
Database : Connected
Drupal bootstrap : Successful
Drupal user : Anonymous
Default theme : bartik
Administration theme : seven
PHP configuration : /etc/php5/apache2/php.ini
Drush version : 4.5
Drush configuration :
Drush alias files : /home/juampy/.drush/drupal.alias.drushrc.php
Drupal root : /home/juampy/projects/drupal/
Site path : sites/default
File directory path : sites/default/files

We first executed the site-alias command to list our configured aliases, from which we could verify that Drush discovered our site alias. Then we checked the status of our test Drupal site by running drush @drupal status. If you remember Telling Drush Which Site to Work With in Chapter 1, Installation and Basic Usage there were two ways of executing a command for a particular site:

  1. Going to the directory where the settings.php is and run the command there unless settings.php is at sites/default, in which case we can run it from the root path:
    $ cd /home/juampy/projects/drupal/sites/drupal.localhost
    $ drush cache-clear all
    'all' cache was [success]
    
    
  2. Adding the --root and --uri as options when executing the command from any directory in our system:
$ drush --root=/home/juampy/projects/drupal uri=drupal.localhost cache-clear all
'all' cache was [success]

Now with our Drush site alias we can execute commands about our site by just adding @drupal before the command name, such as the following:

$ drush @drupal cc all
'all' cache was was cleared [success]

The previous command is actually reading the options defined at the array located at $HOME/drush/drupal.alias.drushrc.php and adding them to the command. This is why it can find it and execute it successfully.

Tip

Executing drush --full --with-optional site-alias @self >> ~/.drush/mysite.alias.drushrc.php from a site within the sites directory will print a basic alias array into a site alias file. This is a very useful way to start configuring site aliases.

Organizing Site Aliases within our system

As you may have noticed, defining site aliases for our local sites is an efficient way of shortening frequently used commands. We may have many sites and therefore end up with many site aliases. Hence, it is good to know how best to organize them.

Site aliases will be scanned and loaded from the following locations and in this order (paraphrased from drush topic docs-aliases):

  1. If you define a drushrc.php configuration file at the root of your site, Drush will inspect it to see if $options['alias-path'] is defined and look for site aliases there. You can also set this by adding the option --alias-path in the command line. Further info about this on Using Configuration Files is at the end of this chapter.
  2. Any of the following locations:
    • $ETC_PREFIX/etc/drush, where $ETC_PREFIX is an environment variable.
    • In the directory where Drush has been installed. For example, at /usr/share/drush.
    • Inside the aliases folder where Drush has been installed, such as /usr/share/drush/aliases.
    • At the .drush directory located at your home path. This is the recommended location.
  3. Inside the sites folder of any loaded Drupal site.

There are three ways of defining site aliases in files:

  • Single site aliases that reference one site can be placed each in a separate file called ALIASNAME.alias.drushrc.php, such as the file we created in the previous section with the filename drupal.alias.drushrc.php.
  • Different site aliases from different and non related sites can be placed together in a single file called aliases.drushrc.php. Here is an example of how could we remove drupal.alias.drushrc.php and define it next to other site aliases at $HOME/.drush/aliases.drushrc.php:
    <?php
    /**
    * @file
    * Definition of several site aliases
    */
    $aliases['drupal'] = array(
    'root' => '/home/juampy/projects/drupal/',
    'uri' => 'drupal.localhost',
    );
    $aliases['drupal8'] = array(
    'root' => '/home/juampy/projects/drupal8/',
    'uri' => 'drupal8.localhost',
    );
    $aliases['anothersite'] = array(
    ...
    
  • A group of related site aliases can be put together at a file called GROUPNAME.aliases.drushrc.php. This gives some extra benefits such as inheriting properties from other site aliases and namespacing site aliases in the form of @GROUPNAME.alias when using them in the command line. This format comes in handy when defining site aliases for local, development and production sites, where they may be located in different systems but refer to different instances of the same website. We will go over its details in the next section through a practical example.

Interacting with remote sites

A very common scenario in the development process of a Drupal site is having a local copy of the site in our local system, another in a development server, and a third one in the production server. Remote site aliases make interactions between these three incredibly easy and give us the chance to invoke commands against the remote sites without even having to login there first. However, dealing with remote sites requires that we have previously established password-less authentication with each server through SSH and a Public Key.

If you already have SSH access to a remote server where a Drupal site is installed, you can set up password-less access in Linux and Mac with the following steps. Instructions for setting up password-less SSH access in Windows can be found at http://drupal.org/node/1418122.

  1. Generate a public key for your user if you do not have one already with the following command. Execute the following command and hit Enter on every prompt:
    $ ssh-keygen
    
    
  2. Copy your public key to the remote server. Replace username and hostname in the command by your SSH username and server domain or IP address. Enter the password of your SSH account when asked:
    $ ssh-copy-id username@hostname
    username@hostname's password:
    Now try logging into the machine, with "ssh 'username@hostname'", and check in: ~/.ssh/authorized_keys
    to make sure we haven't added extra keys that you weren't expecting.
    
    
  3. Our key has been added and now we do not need to enter a password to identify ourselves. Try to login into the server:
$ ssh username@hostname
Welcome!

Note

If you have any trouble setting up password-less SSH authentication, you can find plenty of debugging information at http://drupal.org/node/670460.

Grouping related Site Aliases

Let's suppose that we maintain a website about a music festival (we will call it http://festival.drush). For this website we have a Drupal site configured at our local system, a development environment in another system, and the production environment in a third one. We have already tested that we can access the development and production systems through SSH without typing a password. If you have a similar scenario or can set up one for testing, you will be able to customize the following examples to fit your scenario. If you do so, it is recommended to add the --simulate option to your commands in order to avoid unexpected results.

Creating a Grouped Alias file with our Local Site Alias

In the previous section, we said that we could group related site aliases together in a single file named with the GROUPNAME.aliases.drushrc.php format. Therefore, we are going to create a file named festival.aliases.drushrc.php at our .drush folder located in our home directory with the site alias definition of our local copy of Festival:

<?php
/**
* @file
* Site aliases for Festival website
*/
/**
* Local site alias (http://festival.localhost)
*/
$aliases['local'] = array(

'root' => '/home/juampy/projects/festival',
'uri' => 'festival.localhost',
);

The previous site alias looks exactly the same as the ones we have previously defined apart from the highlighted line, but the first difference we will encounter by placing it within a file with the filename GROUPNAME.aliases.drushrc.php is visible when we list the available site aliases:

$ drush site-alias
@festival.local

In the previous site alias that we defined, the array index at $alias was then the resulting @alias that we would use later in our commands, however, in a grouped site alias, the group name prefixes our site alias name (that is why it is @festival.local and not @local). For example, if we wanted to clear the cache we would use the following syntax:

$ drush @festival.local cache-clear all
'all' cache was cleared [success]

Adding a Site Alias for the development site

Now we are going to add another site alias that will connect us with the copy of Festival in the development server. Add the following at the end of festival.aliases.drushrc.php:

/**
* Development site alias (http://festival.dev.drush)
*/
$aliases['dev'] = array (
'uri' => 'festival.dev.drush',
'root' => '/var/www/festival.dev.drush',
'remote-user' => 'username',
'remote-host' => 'festival.dev.drush',

);

Now our site alias file for Festival has two site aliases: one for our local site and one for the development site. We have added two new properties there that define the username and hostname used for the SSH connection (this means that the connection command used internally will be ssh [email protected]). You should replace these two by the username and hostname of the remote system that you want to connect to. The uri and root options define properties about the Drupal site installed in that server.

If we now list the available site aliases, we will see how the namespacing property of grouped site aliases makes the resulting site alias names meaningful:

$ drush site-alias
@festival.local
@festival.dev

In the previous output, we can see that our site aliases for Festival are prefixed by the GROUPNAME defined in the alias filename, and the rest is the index that we defined in the $alias array. Now you should verify that the new site alias is correctly configured by obtaining information about the remote site:

$ drush @festival.dev core-status
Drupal version : 7.10
Site URI : festival.dev.drush
Database driver : mysql
Database hostname : localhost
Database username : festivaldevdrush
Database name : festivaldevdrush
Database : Connected
Drupal bootstrap : Successful
Drupal user : Anonymous
Default theme : bartik
Administration theme : seven
PHP configuration : /etc/php5/cli/php.ini
Drush version : 4.5
Drush configuration :
Drush alias files :
Drupal root : /var/www/festival.dev.drush
Site path : sites/festival.dev.drush
File directory path : sites/festival.dev.drush/files
Private file directory path : sites/festival.dev.drush/private/files

If you got an output similar to the previous one, you have successfully configured your remote site alias. Now you can make use of all the commands we have already explained against this Drupal site without having to login into the remote system. Go ahead and try some commands to see how this could help you in other projects.

Things we can do with remote Site Aliases

So far we have our remote site alias working and we can do a lot with it, but the real power of remote site aliases comes when we synchronize a local site with a remote site or vice versa. Synchronizing helps us automate the following scenarios:

  • Extract a MySQL dump of a remote site, download it, and load it into the database of our local copy of the site. This is done with the sql-sync command.
  • Copy the directory structure (or any subdirectory) from a remote site into our local site. This is done by the core-rsync command and it is useful for downloading the contents of the files directory.
  • Assuming that our local and development sites are working, we will start by configuring our site aliases in order to synchronize databases between them.

Note

If you have problems setting up site aliases or testing the commands listed in the following sections, add the option --verbose to the command and try to debug what is going wrong by reading the extra output that this option produces.

Synchronizing databases

We are going to add some options to our @festival.local and @festival.dev site aliases so we can synchronize their databases. We basically need to add a path to store temporary database dumps generated on the execution of the sql-sync command and some extra performance options.

Update the file festival.aliases.drushrc.php with the following highlighted pieces of code:

<?php
/**
* @file
* Site aliases for Festival website
*/
/**
* Local alias (http://festival.localhost)
*/
$aliases['local'] = array(
root' => '/home/juampy/projects/festival',
'uri' => 'festival.localhost',
'path-aliases' => array(
'%dump-dir' => '/tmp',

),
);
/**
* Development alias (http://festival.dev.drush)
*/
$aliases['dev'] = array (
'uri' => 'festival.dev.drush',
'root' => '/var/www/festival.dev.drush',
'remote-user' => 'username',
'remote-host' => 'festival.dev.drush',
'path-aliases' => array(
'%dump-dir' => '/tmp',
),
'source-command-specific' => array(
'sql-sync' => array(
'no-cache' => TRUE,
'structure-tables-key' => 'common',
),
),
'command-specific' => array(
'sql-sync' => array (
'no-ordered-dump' => TRUE,
'sanitize' => TRUE,
'structure-tables' => array(
'common' => array('cache', 'cache_filter', 'cache_menu',
'cache_page', 'history', 'sessions', 'watchdog'),
),
),
),

);

We have added one option to our local site alias (@festival.local) and two to the remote one (@festival.dev). Following is a description of each of them:

  • path-aliases (present in both site aliases) is an array of variables used by some commands. The help information of the sql-sync command suggests that we define a temporary path in both site aliases (the one that will generate the database dump and the one which will receive it) for storing the MySQL dump files. Alternatively, this can be provided by appending the --source-dump and --target-dump options when executing sql-sync in the command line.
  • source-command-specific defines a few properties for the site alias used as a source for the sql-command. In this case, we do not want to cache database dumps, which means that a database dump is generated every time we call the command, and we are also stating that we want to ignore the data of a set of tables defined in the next option. These two options could be given at run time by appending --no-cache and --structure-tables-key=common in the command line.
  • command-specific sets a few options for the sql-dump command. This is the same as adding --sanitize and --no-ordered-dump in the command line when sql-sync is executed. Here is the meaning of each one:
    • sanitize resets automatically user email addresses to user+%uid@localhost and passwords to password.
    • Options such as --sanitize-passwords and --sanitize-email can also be used to specify how these two should be sanitized.
    • no-ordered-dump avoids the database entries to be sorted, which speeds up the process.
    • structure-tables defines the an array with table names whose data should not be extracted (for example, the cache tables).

Note

You can set specific settings for the source site alias and the target site alias by using the options --source-command-specific and --target-command-specific. Read the contents of drush topic docs-aliases for more information.

Now let's test our command and synchronize the remote database with our local one. Depending on the size of the remote database and the available bandwidth this could take some time to complete. It is important to provide the site alias names in the right order for this command to work as expected. The first one is the source site alias from which the data will be extracted, and the second one is the target site alias to receive the data:

$ drush sql-sync @festival.dev @festival.local
The following tables will be skipped:
cache, cache_filter, cache_menu, cache_page, history, sessions, watchdog
You will destroy data from festival and replace with data from festival.dev.org/festival.dev.org.
WARNING: --sanitize was specified, but deferred (e.g. the source site is remote). The sanitization operations will be determined after the database is copied to the local system and will be run without further confirmation. Run with --confirm-sanitizations to force confirmation after the sync.
You might want to make a backup first, using the sql-dump command.
Do you really want to continue? (y/n): y
The following post-sync operations will be done on the destination:
* Reset passwords and email addresses in user table

If you got an output such as the previous one, you successfully synchronized the remote database with your local one. As you can see in the output, the list of tables we specified was skipped (their data was not extracted) and after the database dump was loaded in our local system the sanitization process started. Now you have a copy of the remote database in your local host. If you wanted to synchronize your local database with the remote database, you could run the following command:

$ drush sql-sync @festival.local @festival.dev 
--structure-tables-key=common --no-ordered-dump 
--sanitize=0 --no-cache

Note

In order to set up security rules that avoid someone from accidentally upload his local database to the remote site, read the contents of drush topic docs-policy.

Synchronizing directories

There will be times when we need to obtain source code from a remote site to our local copy. The command core-rsync copies a full Drupal directory tree between sites identified by site aliases.

In its simplest form, we just need to define the source site alias and the destination site alias, like we did for the sql-sync command. In the following example, we are downloading all source code and files from the remote site (http://festival.dev.drush) to our local one (http://festival.localhost):

$ drush core-rsync @festival.dev @festival.local
You will destroy data from /home/juampy/projects/festival/ and replace with data from username@hostname:/var/www/festival/
Do you really want to continue? (y/n): y

It is good practice to read the confirmation message where the source site alias and the target site alias located in the synchronization. If you need to do this frequently, it is an even better practice to pull code via Git rather than using drush rsync.

When we execute the command we can specify paths next to each site alias. Placeholders can be defined at the path-aliases option within the site alias definition. Drush adds one for us automatically for handling the files directory of a site. This means that we can easily synchronize our files directory with the folder in the remote site with the following command:

$ drush core-rsync @festival.dev:%files @festival.local:%files

Note

For more options and specific synchronizations, read the available help information at drush help core-rsync.

Sharing configuration within Grouped Aliases

We are about to add a third alias to our group aliases file that will represent the production environment of the Festival website. The most logical step would be to open festival.aliases.drushrc.php and copy the array that defines the development environment to a new entry called prod and edit each of its options. However, we are going to make use of the parent option within the site alias definition to reuse the configuration of the development alias.

The following is how our festival.aliases.drushrc.php looks after adding the new site alias. Note that if you are following this with your own production site, you will have to alter each setting so it fits your scenario:

<?php
/**
* @file
* Site aliases for Festival website
*/
/**
* Local site alias (http://festival.localhost)
*/
$aliases['local'] = array(
'root' => '/home/juampy/projects/festival',
'uri' => 'festival.localhost',
'path-aliases' => array(
'%dump-dir' => '/tmp',
),
);
/**
* Development site alias (http://festival.dev.drush)
*/
$aliases['dev'] = array (
'uri' => 'festival.dev.drush',
'root' => '/var/www/festival.dev.drush',
'remote-user' => 'username',
'remote-host' => 'festival.dev.drush',
'path-aliases' => array(
'%dump-dir' => '/tmp',
),
'source-command-specific' => array(
'sql-sync' => array(
'no-cache' => TRUE,
'structure-tables-key' => 'common',
),
),
'command-specific' => array(
'sql-sync' => array (
'no-ordered-dump' => TRUE,
'sanitize' => TRUE,
'structure-tables' => array(
'common' => array('cache', 'cache_filter', 'cache_menu', 'cache_page', 'history','sessions', 'watchdog'),
),
),
),
);

/**
* Production site alias (http://festival.drush)
*/
$aliases['prod'] = array (
'parent' => '@festival.dev',
'uri' => 'festival.drush',
'root' => '/var/www/festival.drush',
'remote-user' => 'username-prod',
'remote-host' => 'festival.drush',
);

The option'parent' => '@festival.dev' is telling Drush that we are inheriting all the options defined at the $aliases['dev'] array. This means that we can just focus on defining what is different in this site alias, which are options such as the uri and root path, the connection parameters (remote-user and remote-host), and the location of the files directory.

After doing this, we finally have a structure of three namespaced site alias like the following example:

$ drush site-alias
@festival.local
@festival.dev
@festival.prod

As you can see, there is an alias defined for each environment and we could copy the festival.aliases.drushrc.php file to other systems and use it by just adapting the local site alias. Now we can download a sanitized version of the production system to our local system with the following command:

$ drush sql-sync @festival.prod @festival.local

The output must have been almost identical to the development system. Drush detected that we want to sanitize the database (it actually loaded this option from the inherited alias @festival.dev) and decided to postpone it until the database dump had been loaded to our local Drupal site.

Tip

If you are not sure about what would be the result sql-sync or a core-rsync command, you can always simulate it by adding the --simulate option at the command line.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.111.85