6

I'm creating a multi-site instance for a client that makes heavy use of Webform. It's going to be a survey tool of sorts with a single base domain (no sub-domains) and a single SSL certificate.

I've set up the /sites/default the base of what we'd like all other sites to be like. I've gone so far as to attempt this using bash. (This is not my best code and it lives on a throw away VM*):

# Create temporary password
PASS=`tr -dc a-z1-4 </dev/urandom  | head -c 10`

# File structure and empty settings file
mkdir /var/www/html/sites/$1
mkdir /var/www/html/sites/$1/files
cp /var/www/html/sites/default/default.settings.php /var/www/html/sites/$1/settings.php

mysql -u root -p -e "create database $1"
mysql -u root -p -e "GRANT ALL PRIVILEGES ON $1.* TO '$1'@'%' IDENTIFIED AS PASSWORD('$PASS');"

# And here is where things fall apart
drush si ???

My question is, is there a module or utility that could help create a new site inside this multi-site installation? That is, I'd like to clone the model database, create a /sites/new-site/settings.php, and enable a chosen set of modules.

My dream would be to have a drush clone-site command.

8
+50

Take a look at Aegir:

It's probably a bit more than what you are looking for, since it manages your web server vhosts (apache or nginx), which means that it kind of takes over part of the system configuration. It also works much better on Debian (with Debian packages, installation/upgrades are pretty easy.. kind of annoying otherwise).

Once it's installed, you can create your base site and clone it using the Aegir user interface (which is a Drupal site, called the "hostmaster", which is completely autonomous from the other sites you are hosting - it's just that as Drupal developers, they used Drupal for the front-end to their tool). Under the hood, Aegir uses Drush, so it's not re-inventing the wheel.

Anyway, fair disclaimer: there is a learning curve, but it has a pretty good community and it's well worth it when managing farms of small sites. It also has commercial training/support available from a few companies (listed on the project page).

  • An upvote for a great answer, but I'm still holding out hope for a smaller utility. – Rick Oct 27 '14 at 21:25
  • @richard Aegir does most of the job with the drush extension provision. Take a look at that separately from all of Aegir. – Letharion Oct 27 '14 at 21:42
  • I thought Aegir was still only D6 compatible – tenken Oct 28 '14 at 4:59
  • @tenken: the Aegir front-end itself (the hostmaster install profile) is just a web interface to what happens under the hood (provision and drush). As of Aegir 2.x (current stable), it is still a Drupal6-based web interface, but it can manage Drupal 6/7/8 sites. Aegir 3.x, currently in beta, is a Drupal7-based interface. The only impact, however, is if you are customizing the management front-end. – bgm Oct 28 '14 at 12:58
  • 1
    @Richard: Sorry it caused you troubles. I know it's a bigger time investment, but if you have the option, I would strongly recommend a Debian server, and then you can use the excellent .deb packages for Aegir. I agree that manual installation is difficult, and manual upgrades are too. It's more work, and is not always worth it to be very honest, but it does have the benefits of a pretty standard stack and a community of users. – bgm Oct 30 '14 at 15:25
7

There is no single management utility (maybe some managed cloud solutions) which can easily manage your all Drupal instances, so you have to learn how to mix different tools together (e.g. Puppet + drush). Most of it can be done by drush.


Ansible

Ansible is a flexible and extensible automation tool which definetly can help with multisite deployment.

See:


Puppet

Probably you don't need it, but in case you'd need to set-up whole LAMP configuration each time (e.g. on multiple servers), you should use some configuration management utility.

For example to automatize LAMP environment configuration (Linux, Apache, MySQL and PHP) you can use either Puppet or Chef. Having proper Puppet recipe, you're able to configure whole LAMP configuration in one command. Check some basic recipe example for ADS distribution: ads.dev.pp.

Installing Puppet is easy (sudo apt-get -y install puppet), then you've to install necessary modules (e.g. for Apt, Apache and Pear). In example:

sudo puppet module install puppetlabs/apt; sudo puppet module install rafaelfc/pear; sudo puppet module install puppetlabs-apache

For more advanced recipe (different db per vhost), check: Proper way of importing many manifest files with vhost definitions.


Drush remotes

Once you've LAMP environment ready, you need to define your remote shell aliases, so you can transfer your files and database across your sites. Check example.aliases.drushrc.php how to use it.

You can use different remotes for each multi-site instance, e.g.:

// The site in sites/default/
$aliases['site.default'] = array(
  'uri' => 'default',
  'root' => '/path/to/drupal',
);
// The site in sites/site1/
$aliases['site.site1'] = array(
  'uri' => 'site1',
  'root' => '/path/to/drupal',
);

Make sure that you'll add your SSH key into your authorized_keys, so it won't ask you for the password each time when running remote commands. See: How to add RSA key to authorized_keys file?.


Site installation

If you'd like to install Drupal sites from scratch, consider using Drupal installation profiles or drush make files (writing one or generating from the existing site).

You can simply check how distributions such as Recruiter, Commerce Kickstart or ADS work.

For complex solutions, you may use phing (or ant). Check example of build.xml from ADS or check Template Phing build.xml file for Drupal projects.

See also: What is the easiest way to install clean Drupal from scratch?


Transfering the files to the remote

Once you have your shell aliases set-up, transferring files is easy.

In example:

drush -v rsync drupal/ @remote

Multi-site example:

drush -v rsync drupal/ @remote1,@remote1

Or this can be achieved by defining each e.g. dev alias in separate *.aliases.drushrc.php group alias files, so calling @dev would invoke all defined dev environments.

See also: How to rsync files between two remotes which share the same host?


Synchronising database between sites

Transfering database is easy as well by drush sql-sync, e.g.:

drush sql-sync @self @remote

This will transfer your local Drupal database into remote. You can also use the same command to transfer the database between two remotes.


Managing settings file

You can consider to edit your settings.php and include at the end extra file such as settings.local.php as your instance-specific configuration file (example 1, 2), then it'll be easier to maintain (as it can be ignored by git). So if you have multiple environments, you can use the following simple approach to load the settings based on your current environment:

$conf['environment'] = $env = 'local'; // dev, test, prod)

And use the simple switch statement to invoke different settings per environment.

Here are the example settings files from ADS distribution which you can use.

If you want to automate changes to your settings file, you can define some drush alias to do something like sed s/DB_NAME/real_db_name/ (drush normally accept arguments and pass them to the remote), or check Can you modify the settings.php file using drush?.


Drush shell aliases

If you want your dream to come true, use drush shell aliases to define your commands which you'd like to execute on remotes as part of your deployment script.

Same examples for your remote:

$aliases['dev'] = array(
'shell-aliases' => array(
  'deploy-code' => '!git fetch origin && sudo git stash && sudo git reset origin/dev --hard',
  'deploy-db' => '!drush sql-sync --yes @prod @self',
  'deploy-files' => '!drush --yes rsync @prod:%files @self:%files',
  'deploy-drupal' => "!
    sudo -uwww-data drush -y updb &&
    sudo -uwww-data drush cc all &&
    sudo -uwww-data drush -y fra &&
    sudo -uwww-data drush cron &&
    sudo -uwww-data drush status-report --severity=2 &&
    echo Deployment completed.
  ",
));

And then you can combine them by defining your local aliases in your drushrc.php, e.g.

$options['shell-aliases'] = array(
  'deploy-dev' => '!drush @dev deploy-db && drush @dev deploy-code && drush @dev deploy-files && drush @dev deploy-drupal',
);

So by running simply drush deploy-dev it will transfer the files and database from prod into your testing (dev) environment, run updates, clear cache, run cron, revert all features, etc.


Your use case

Based on above, your use case can be solved by the following commands on local:

  1. Clone the site:

    drush -yv @site exec drush rsync sites/site-1 sites/site-2
    
  2. Upload the settings file and modify the database:

    drush rsync examples/default.settings.local.php @site:sites/site-2/settings.local.php
    drush -vy @site exec sed -i -e s/DB_NAME/real_db_name/ sites/site-2/settings.local.php
    
  3. Transfer the db between sites.

    drush -vy @site sql-sync --create-db site-1 site-2
    
  4. Enable chosen set of modules:

    drush -vy @site en module_1 module_2
    

You can create easily the drush alias for that. E.g.

drush clone-site site-1 site-2 # Last 2 are arguments.

Eventually check how to use policy.drush.inc, so you can add your own pre-process, post-process code for any of your drush command.


Read more:

5

I would install provision.

It's the backend part of Aegir, implemented as a drush extension.

It literally contains the command you are looking for: provision-clone, which will allow you to Clone a site between platforms. In provision language, "platform" is a Drupal install. You could just clone the site within the same platform though.

You also have another option in these two commands:

  1. backup - Generates a tarball containing the sites directory, the site data configuration and the database dump.
    • This allows the tarball to act as a 'site package', which can be redeployed on other installations, or used for an upgrade.
  2. deploy - Accepts a site package (backup) as argument, and redeploys it, running the upgrade processes on it.
    • Uses hook_provision_pre_upgrade(), hook_provision_upgrade() and hook_provision_post_upgrade() hooks, and allows clean roll back if any errors occur. Will include stringent checking of module versions, and allow unit tests to be run.

You can completely skip hostmaster, the UI part of Aegir, and work with provision on it's own. Among commonly known projects, I believe this is the closest you will get to what you want.

2

Unfortunately there is no module to do that you need. A website can’t (and must not) manage the Apache and the MySQL.

Script base method: On the past there were many tries to manage Drupal multi-sites with scripts.

You can enhance your custom scripts with Drush, using something like drush -l site_name command or drush @site_name command (this is why the drush si fall apart in your script). But it will automate only the site management and not the site deployment (MySQl, apache Vhost etc).

Aegir: As mentioned before by @bgm the “must” way of Drupal multi-site is Aegir. Aegir 2.x is Drupal 6 and consists but 2 major parts (+2 for UI)

  • Hostmaster (A Drupal 6 install that manages the other parts)
  • Provision (All the Drush based magic to deploy & manage sites)

So if you like to invoke custom scripts and break the Aegir/Drupal best practices but you want to automate site deployment you can use the Provision on a custom way over Drush. But I don't suggest this approach...

Aegir has a steep learning curve (especially if you don’t have help of OPS) but not only you will have an easy deploy/update/management Drupal server but also you will forced to learn and follow Drupal best practices.

1

Take a look at Druml. It works perfectly with Drupal Multisites.

0

To round out some of the answers here, there is also OpenDevShop. It aims to be an Acquia Cloud / Pantheon type hosting environment you can install on your own servers to manage your infrastructure and sites.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.