Drupal Association members fund grants that make connections all over the world.
This document reflects drush-3.0-beta2 and later versions.
At the time of this writing, the most recent drush tag is drush-3.0-beta1, which contains a different implementation of the site alias feature.
Please note that Drush has moved to Github.
Drush has introduced the concept of 'site aliases', which are small arrays containing connection details relevant to individual site instances. These are used to note information about your local dev site and a remote staging site (for example).
With this info, drush can help you move content between these locations!
After installing drush, have a look at:
drush help site-alias
drush help rsync
drush help sql-sync
to get started.
You will first want to make a note of your local site alias information.
About the local setup
If I am working on a drupal multisite instance called
demosite.drupal6.local, my working site directory may be something like
I will be wanting to connect to a location called
demosite.staging.remote. These are our two 'site aliases'.
As implied, the aliases can actually be shorter names, like '@dev' and '@stage'. In the context of a Drupal site, you can also use the name of the site as it appears in the 'sites' folder. In order for this to work, you must have -r / --root set in your drushrc.php file, or your current working directory must be inside the Drupal root. If you have done this, you can use the site folder name as a site alias, like so:
drush site-alias --full demosite.drupal6.local
This tells us:
$aliases['demosite.drupal6.local'] = array ( 'uri' => 'demosite.drupal6.local', 'root' => '/var/www/drupal6', );
Pretty simple so far. There is more to it.
Enter information about the remote target peer alias
We also need to have some information about the destination site. The remote site is (of course) not local, so the local drush knows nothing about it until we tell it. As mentioned in the help documentation
drush help rsync, you can read 'example.aliases.drushrc.php' to see an example of how this can be done.
Your own aliases configuration file can be placed in several places. Since the remote site for demosite.drupal6.local is only relevant to this site, I will put it in the local site dir as
Edit the file (create it if needed)
To add the remote sites information:
$aliases['peer'] = array ( 'uri' => 'demosite.staging.remote', 'root' => '/var/www/vhosts/staging/httpdocs', 'remote-host' => 'mystagingserver.myisp.com', 'remote-user' => 'publisher', );
Tip: This is documented much more in the example.aliases.drushrc.php distribution.
Tip: Creating the site-alias config array is tedious by hand. If you have a working site, you can just ask it to give you all the details like so:
Change into the site dir of a working site and run
drush site-alias --with-db --show-passwords --with-optional @self
I often go
drush site-alias --with-db --show-passwords --with-optional @self > /etc/drush/mysqit.alias.drushrc.php
and then importantly edit the resulting new files and A: add a
<?phptag to the top! B: relabel it from @self to your preferred nickname - which must match the filename you used.
Those extra connection details are required for remote aliases.
If you want, you can also split out the component parts of an alias and use inheritance to construct the peer alias. For example:
$aliases['mystagingserver'] = array ( 'remote-host' => 'mystagingserver.myisp.com', 'remote-user' => 'publisher', ); $aliases['peer'] = array ( 'parent' => '@mystagingserver', 'uri' => 'demosite.staging.remote', 'root' => '/var/www/vhosts/staging/httpdocs', );
Check that this information is now available to drush.
drush demosite.drupal6.local site-alias # Fetch a list of known sites drush demosite.drupal6.local site-alias --full @peer # Show what we know about the named site
... it should reflect back the connection details we've entered. Note that because we placed the '@peer' alias inside the site folder for our demo site, this alias is only known in contexts where that site has been named or bootstrapped by drush. Had we put the alias file inside of a more global location such as $HOME/.drush, then it would be globally available. In that case, we would probably want to use an alias name that is a little less generic than 'peer'.
It may feel strange to put the alias context, demosite.drupal6.local in the previous example, on the left side of the site-alias command. A more direct way to specify the context of the @peer alias would be to use relative alias syntax:
drush site-alias --full demosite.drupal6.local/@peer
drush rsync the files
The first time we do this, it will create the remote site entirely from scratch (it didn't exist before). This uses rsync under the hood, so it will do only incremental updates and preserve permissions etc if possible.
drush rsync demosite.drupal6.local @peer
You will destroy data from firstname.lastname@example.org:/var/www/vhosts/staging/httpdocs/ and replace with data from /var/www/drupal6/
Requirement: For drush to communicate with remote servers, you must first set up ssh authentication keys to assist automated logins. If you haven't already, go and look into this. It's pretty easy once you know how, and a huge win for productivity. greg.1.anderson has supplied a script that may help this set-up. It only has to be done once per user account per server.
... Cool. The remote site has all the current files up there now!
Gotcha: This command put up everything, even the unrelated multisites I had hanging around. There are probably tidier ways to do this.
Aside: a fix for multisite sites folder aliases
I'm not using the sites/default directory, which means my local and remote hosts will have a slightly different expectation about the sitename I will use for the site instance. This can cause trouble, but a quick, helpful way to deal with this is to just symlink the site directory with the alternative name.
On the remote site:
cd /var/www/vhosts/staging/httpdocs/sites; ln -s demosite.drupal6.local demosite.staging.remote
... now the remote site will serve the same content and as the local one. There are other ways to work around this issue, and this approach can have side-effects, but that won't be covered here.
Sync the database
We'll also need to push up the database. It can be done in one line if everything is already set up at the other end.
The remote site will not quite use the same settings, because we'll need different database settings etc. Cleverly, the rsync has carefully chosen to
(see "drush help rsync")
This means we get to define the remote DB settings separately, as required.
If you've not already done so, set up your database however you normally would on the remote site. This is different between hosts, so probably not automated.
Quickest is to [CREATE DATABASE; GRANT PRIVILEGES; Copy and change the settings.php by hand to edit the $db_url], although you can probably even run the Drupal install wizard if you like.
With the remote database ready to take the content, we'll push it up. This will over-write anything that used to be there.
drush sql-sync demosite.drupal6.local @peer
This command will actually log in to the remote site, and investigate the settings found there to find out what the remote database connection string is. Pretty nifty. You can do other things remotely using this channel also.
This is easiest if drush is also available on the remote site. If you've not already set this up, you can use drush to push itself to a remote server:
drush rsync demosite.drupal6.local:%drush @peer:%drush.
You can avoid installing drush remotely by noting the database connection details locally in the site-aliases array.
Gotcha: Depending on how you installed it, the commandline install of the drush program may not be found on the remote site when running a non-interactive shell session. This can be frustrating.
To work around this, the alias file allows you to define
path-aliases['%drush-script'] = '/path/to/drush';.
See example.aliases.drushrc.php. NOTE the parameter '%drush-script' must link to the drush shell script file or the parameter '%drush' must link to the drush directory. Either works.
Tip: Pay attention to the advice in example.aliases.drushrc.php on creating a designated '!dump' file path. Note that
%dumpis a file name, not a folder, and the directory structure to it must already exist.
for mine, I set it to:
'%dump' => '/var/www/vhosts/staging/data/dump.sql',
drush sql-syncis not yet aware of database prefixes and may transfer a heck of a lot more than you wanted.
If you got this far, and worked through any troubleshooting issues, you should now have a working remote clone of your site.
From now on it will be MUCH easier, and you can sync file and DB up and down, selectively or in bulk.
Note: Running any drush command with -y or --yes will assume 'yes' as an answer to all prompts, which is useful when scripting the synchronization or deployment of sites.
to push up some recent changes to a theme from dev to staging
drush rsync demosite.drupal6.local/sites/all/themes/demo1/ @peer:sites/all/themes/demo1/
to fetch the latest files that may have been uploaded to the staging site
drush rsync @peer:%files/ demosite.drupal6.local:%files
It probably be a good idea to flush the site caches before transferring the db from local, or on the remote site after a db transfer. drush provides a shortcut for that.
drush cc all
(run on either local or remote system, respectively)
(there are probably more shortcuts also)
Managing remote sites with drush aliases
Once you've got remote aliases set up, you can run drush commands on them directly from your local commandline. Drush will handle to logins and relative paths needed.
drush @peer status
- Check for an alias entry named 'peer'
- Log in to the remote-site using the given credentials
- Move to the appropriate directory, or at least use the correct remote paths
- invoke drush there to carry out the command
- and return the result
This should work for most drush actions, just by putting an @alias identifier before the commands. Internally, this triggers the functions
drush @peer update drush @peer cc
Will run DB updates or clear the cache on a remote site without you ever leaving the comfort of your local shell.
To work fully, the remote site must have drush installed also. See the note above about
path-aliases['%drush-script'] = '/path/to/drush'; if you are having trouble getting that to work.
Further control over remote syncing
It is also possible to add options to site alias definitions to provide finer-grained control over how the sync operations will be preformed. See the blog post Drush aliases primer for Live->Dev syncing on emspace.