My multi-site Drupal install, using Apache (with named virtual hosts) and MySQL on Ubuntu, is now running nicely.

<p>But I want an easy way to create new Drupal sites.</p>


<p>I have already formed a systematic process of creating and configuring new sites, so I just had to write a Bash script of that process.</p>


<p>This is my first experience using Bash properly, with cool commands like sed.</p>

drupal_create.sh $new.sitename.com $password <ul> <li>Stops Apache.</li> <li>Copies the “default” Drupal site as a new site – drupal/sites/new.sitename.com</li> <li>Creates an MySQL database – MySQL $ databases $ new_sitename_com</li> <li>Creates an MySQL user and grants full access – GRANT ALL ON new_sitename_com.* TO [email protected] IDENTIFIED BY ‘password’</li> <li>Copies and modifies a drupal.template apache config file for the new site – /etc/apache/sites-available/new.sitename.com</li> <li>Enables the new site and starts Apache.</li> <li>Makes the site’s settings.php writable – chmod a+w drupal/sites/new.sitename.com/settings.php</li> <li>Sets the database URL in the settings.php – dburl=”mysql://new_sitename_com:[email protected]/new_sitename_com” </li> <li>Hits the site’s configuration page to complete it – HTTP GET http://new.sitename.com/install.php?profile=default</li> <li>Restricts access to settings.php – chmod go-w drupal/sites/new.sitename.com/settings.php
drupal_create.sh

#!/bin/bash

sitename=$1
password=$2
drupal_site_path="/home/james/public_html/drupal/sites" 

# database name is the same as site name, with _ instead of .
databasename=$(echo $sitename | sed -e "s/\./_/gi")

# database user is first 16 characters of database name
databaseuser=${databasename:0:16}

# stop apache early to keep things organised
/etc/init.d/apache2 stop

# copy the default drupal site
cp -a $drupal_site_path/default $drupal_site_path/$sitename

# create a database for this site
mysqladmin -u root -p create $databasename

# create a db user and grant ALL access
mysql -u root -p -B -e "GRANT ALL ON $databasename.* TO [email protected] IDENTIFIED BY '$password'; FLUSH PRIVILEGES" 

# copy the drupal apache site template to a new one for this site
cp /etc/apache2/sites-available/drupal.template /etc/apache2/sites-available/$sitename

# replace the template's "site name" placeholder with this site name
sed -i.backup -e "s/DRUPAL_SITE_NAME/$sitename/g" /etc/apache2/sites-available/$sitename

# enable this site in apache
a2ensite $sitename

# start apache
/etc/init.d/apache2 start

# Make the settings.php file writable so the installer can modify it later (I'm only guessing, haha).
chmod a+w $drupal_site_path/$sitename/settings.php

# Set the database configuration
olddburl="mysql:\/\/username:[email protected]\/databasename" 
dburl="mysql:\/\/$databaseuser:[email protected]\/$databasename" 
sed -i.backup -e "s/$olddburl/$dburl/" $drupal_site_path/$sitename/settings.php

# Add a temporary host entry for this site, so we can be certain it will resolve
hostEntry="127.0.0.1 $sitename" 
echo $hostEntry >> /etc/hosts

# Request the install page to finish the configuration
# * I use this method to also ensure the site is running correctly on the webserver.
curl -s http://$sitename/install.php?profile=default

# Remove the temporary host entry
sed -i.backup -e "s/$hostEntry//g" /etc/hosts

# Restrict access to the settings file
sudo chmod go-w $drupal_site_path/$sitename/settings.php

</li> </ul>

drupal.template <ul> <li>This is a template for an Apache named virtual host config file, for Drupal sites.
drupal.template

<virtualHost *:80>

        ServerAdmin [email protected]_SITE_NAME
        ServerName DRUPAL_SITE_NAME
#        ServerAlias www.jl.sg
#    DirectoryIndex index.html
        DocumentRoot /home/james/public_html/drupal

                Options FollowSymLinks

                Options Indexes FollowSymLinks MultiViews

        LogLevel warn
        ErrorLog /home/james/public_html/drupal/sites/DRUPAL_SITE_NAME/logs/error.log
        CustomLog /home/james/public_html/drupal/sites/DRUPAL_SITE_NAME/logs/access.log combined

</virtualHost>

<virtualHost *:443>

    ServerAdmin [email protected]_SITE_NAME
    ServerName DRUPAL_SITE_NAME
#    ServerAlias www.jl.sg

    DirectoryIndex index.html
    DocumentRoot /home/james/public_html/drupal

                Options FollowSymLinks

                Options Indexes FollowSymLinks MultiViews

    LogLevel warn
    ErrorLog /home/james/public_html/drupal/sites/DRUPAL_SITE_NAME/logs/error.log
    CustomLog /home/james/public_html/drupal/sites/DRUPAL_SITE_NAME/logs/access.log combined

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/selfsigned.pem

</virtualHost>

</li> </ul>

drupal_drop.sh $new.sitename.com <ul> <li>Does the reverse of drupal_create.sh, removing the specified Drupal site.</li> <li>does not ask for confirmation!
drupal_drop.sh

#!/bin/bash

sitename=$1
password=$2

databasename=$(echo $sitename | sed -e "s/\./_/gi")
databaseuser=${databasename:0:16}

/etc/init.d/apache2 stop
a2dissite $sitename
rm -R /home/james/public_html/drupal/sites/$sitename
mysqladmin -u root -p drop $databasename
rm /etc/apache2/sites-available/$sitename
/etc/init.d/apache2 start

</li> </ul>

<p><br />** Note: These are links to my actual “production” files, so you’ll obviously need to remove all the James’ness, and modify them to suit your environment.</p>