Install Drupal 7 with a script

The seventh version of Drupal has greatly improved the installation process once more. Among other changes, the installer has become more user-friendly, but the best part is under the hood, and somewhat less obvious. It is now much easier than ever to install Drupal using a PHP script that runs in the console, rather than the interactive web installer.

Since I have not yet seen a detailed documentation of this feature, here is a guide.

1. Build an install script

The central function you need to call (after including install.php in your installation script) is, oddly enough, install_drupal(). The argument you need to pass to this function is less obvious, and here it is, line by line:

<?php $settings = array(
  
# First, tell Drupal you are not using the interactive installer.
  
'interactive' =?> FALSE,

  # This part is required for multisite support. The keys
  # you put here overwrite the $_SERVER array, allowing Drupal
  # to find a site path (in this case, localhost.my.site, my.site etc.
  'server' => array(
    'HTTP_HOST' => 'localhost',
    'SCRIPT_NAME' => '/my/site',
  ),

  # Next, choose the profile and locale Drupal should use.
  # The profile must be in a ./profiles/$profile/ folder.
  'parameters' => array(
    'profile' => 'expert',
    'locale' => 'en',
  ),

  # This is the data that will be submitted to the various 
  # forms in the installation wizard.
  'forms' => array(
    # Database configuration.
    'install_settings_form' => array(
      'driver' => 'mysql',
      'database' => 'db_name',
      'username' => 'db_user',
      'password' => 'db_pass',
      'host' => 'localhost',
      'port' => '',
      'db_prefix' => 'drupalsite_',
    ),
    # Site information, and the data of the root user.
    'install_configure_form' => array(
      'site_name' => 'Drupal Test Site',
      'site_mail' => 'drupal@localhost',
      'account' => array(
        'name' => 'root',
        'mail' => 'drupal@localhost',
        'pass' => array(
          # This is a bit of a WTF, but that's the way it works.
          # Even non-interactively, password fields require two identical values.
          'pass1' => 'hunter2',
          'pass2' => 'hunter2',
        ),
      ),

      # This is the timezone of the Drupal site. You can find the
      # PHP timezone strings at http://php.net/timezones
      'site_default_country' => 'DE',
      'date_default_timezone' => 'Europe/Berlin',

      'clean_url' => TRUE,

      # Check for updates: 
      #   array() = off, 
      #   array(1) = on, 
      #   array(1, 2) = on, and notify by email
      'update_status_module' => array(),
    ),
  ),
);


# Finally, fire it off.
require_once './install.php';
install_drupal($settings);

2. Set up/clean the environment

Note that this script will not clear or prime the site folder, so your installation will only work if a pristine "settings.php" file is in the site folder you want to install to.

The standard procedure to delete and clear a site is, in pseudocode:

if dir "sites/SITE/" exists: database = parse file "sites/SITE/settings.php" delete database tables else make dir "sites/SITE/" done copy file "sites/default/default.settings.php" "sites/SITE/settings.php" run installation script

3. Useful modifications in install.php

One disadvantage I've found is the, well, non-interactiveness of the non-interactive installer. If the installer runs through correctly, running the above PHP code will print no output at all. Since installation can take between 30 and 60 seconds on slow PCs, it would be nice to know the installer's progress. To this end, I put the following lines into the install.php file:

@@ -406,6 +406,7 @@ function install_run_task($task, &$insta
       return;
     }
     else {
+      print "Submitting information to task $function... ";
       // For non-interactive forms, submit the form programmatically with the
       // values taken from the installation state. Throw an exception if any
       // errors were encountered.
@@ -415,6 +416,7 @@ function install_run_task($task, &$insta
       if (!empty($errors)) {
         throw new Exception(implode("\n", $errors));
       }
+      print "done.\n";
     }
   }
 
@@ -437,6 +439,7 @@ function install_run_task($task, &$insta
         variable_set('install_current_batch', $function);
       }
       else {
+        print "Running batch process $function... \n";
         $batch =& batch_get();
         $batch['progressive'] = FALSE;
       }
@@ -469,6 +472,7 @@ function install_run_task($task, &$insta
 
   else {
     // For normal tasks, just return the function result, whatever it is.
+    if (!$install_state['interactive']) print "Running task $function... \n";
     return $function($install_state);
   }

I'll admit that this is a far cry from an actual installation tool that can be packaged, but it should make setting up test environments or deployment a whole lot easier.

News Category: 

Comments

Excellent post. It's worth pointing out, though, that not everyone needs to write their own script in order to use this feature. Drush now has a "drush installsite" command, for example, which is a simple wrapper around this functionality. There is also room to add more features to it for people who want to help out with that; I assume that eventually, most people will wind up using the Drush wrapper script rather than their own custom one.

Your idea of printing out progress information seems like it might be worth submitting as a core patch - for example, there could be a 'verbose' option you pass in with the $settings array that controls whether that is printed or not. I think it would make sense - any interesting in submitting it as a patch?

Also, some (very) minor corrections:
* Setting 'interactive' => FALSE shouldn't be necessary (it figures that out for you).
* I'm pretty sure you no longer need a pristine settings.php file for this to work (that was a bug at one point, but I thought it was fixed?) The intention is certainly that you don't need it; if you have an already-filled out settings.php it should respect the database connection information there, just like a browser-based installation does.

--David Rothstein

Note that you should probably delete the "files/" directory if it exists in the site folder, in order to make sure the site is truly pristine.

I have installed D7.
Now i created a folder xyz.com under sites(/sites/xyz.com) with copying default.settings.php and renaming to settings.php
Now i want to have a drupal installation for this in a non interactive way. how can i do it?
when i tried im getting followin error:

Exception: <ul><li> bye To start over, you must empty your existing database.</li><li>To install to a different database, edit the appropriate <em>settings.php</em> file in the <em>sites</em> folder.</li><li>To upgrade an existing installation, proceed to the <a href="http://localhost/drupal_7/update.php">update script</a>.</li><li>View your <a href="http://localhost/drupal_7">existing site</a>.</li></ul> in install_verify_completed_task() (line 791 of C:\wamp\www\drupal_7\includes\install.core.inc).

© 2006-2012: All content, unless otherwise noted, is the property of Arancaytar. It may be copied and modified with attribution for non-commercial purposes. By publishing comments on this site, you grant Arancaytar a non-exclusive, perpetual license to reproduce and publish these comments along with any identifying information provided. (You may request your comments to be deleted or edited voluntarily.)