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.
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:
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]
--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.
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):
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.$ETC_PREFIX/etc/drush
, where $ETC_PREFIX
is an environment variable. /usr/share/drush
. /usr/share/drush/aliases
. .drush
directory located at your home path. This is the recommended location.There are three ways of defining site aliases in files:
ALIASNAME.alias.drushrc.php
, such as the file we created in the previous section with the filename drupal.alias.drushrc.php
. 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( ...
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.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.
$ ssh-keygen
$ 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.
$ ssh username@hostname
Welcome!
If you have any trouble setting up password-less SSH authentication, you can find plenty of debugging information at http://drupal.org/node/670460.
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.
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]
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.
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:
sql-sync
command. core-rsync
command and it is useful for downloading the contents of the files
directory.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:
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. 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. 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
. --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).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
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
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.
3.133.111.85