Setting up a Multi-Site Drupal 7 Dev Environment on Ubuntu / Mint

Configuring a box for Drupal development, testing server configurations and PHP debugging.

There are a number of ways to setup Drupal on you development box. Below are a list of the steps I use when creating a new project. If you're doing professional work in Drupal, you'll probably be developing for multiple websites. This configuration will allow for multiple sites, Drupal and otherwise. I'll also outline setting up Eclipse, xdebug and various server utilities you may need for testing configurations in your dev environment.

Steps

  1. Setup LAMP
  2. Install Drush
  3. Install Git
  4. Setup Apache
  5. Create a MySQL Database
  6. Setup the PHP Mail Function
  7. Install Drupal 7
  8. Configure Drupal Site
  9. Install Varnish
  10. Install Memcache
  11. Install APC (Alternative PHP Cache)
  12. Setup Solr
  13. Setup Eclipse
  14. Setup XDebug
  15. Configure Logging

LAMP Setup

Synchronize your list of packages with those in the source repositories.
sudo apt-get update
To install the basic lamp setup in Ubuntu, open a terminal and execute the following:
sudo apt-get install lamp-server^
Note the trailing caret; see https://help.ubuntu.com/community/Tasksel for more information on why this is used.

Packages can also be installed individually:
1. Install Apache Web server.
sudo apt-get install apache2
2. Install Mysql server.
sudo apt-get install mysql-server mysql-client
3. Install PHP.
sudo apt-get install php5 libapache2-mod-php5
4. Install PHP Data Objects.
sudo apt-get install php5-common php5-mysql
5. Restart apache.
/etc/init.d/apache2 restart

The GD Graphics Library is required by Drupal, and is used for dynamically manipulating images. To install, execute the following from a terminal:
sudo apt-get install php5-gd
Install the PEAR package manager:
sudo apt-get install php-pear

Drush Installation

Install the command line-ready version of PHP (something Ubuntu packages separately from the lamp-server package):
sudo apt-get install php5-cli
Download and install drush:
cd ~/
wget http://ftp.drupal.org/files/projects/drush-7.x-4.5.tar.gz
#extract to home directory
tar -zxvf drush-7.x-4.5.tar.gz
rm drush-7.x-4.5.tar.gz
#add path to your bash profile:
echo 'PATH=$PATH:~/drush' >> ~/.bashrc

Git Installation

Issue the following command to install Git:
sudo apt-get install git-core

Apache Setup

Because this is a development box, we'll want to setup Apache for multiple sites. This will allow us to run multiple Drupal configurations in an entirely seperate space. It can be very usefull for testing upgrades, or working with different sites outside of a single Drupal instance.
I like to work out of a www directory in my home path:
cd ~/
mkdir www
Next, we'll add an entry to our hosts file so Apache will know which site to load.
sudo gedit /etc/hosts
Add the line:
127.0.0.1 localhost.drupal7
Now we can add a virtual host for localhost.drupal7:
cd /etc/apache2/sites-available
sudo gedit localhost.drupal7
Here's a sample file:
<VirtualHost *:80>
 ServerAdmin email_address
 ServerName localhost.drupal7
 DocumentRoot /home/[username]/www/localhost.drupal7
 <Directory />
  Options FollowSymLinks
  AllowOverride All
 </Directory>
</VirtualHost>
Enable the new site using:
sudo a2ensite localhost.drupal7
Create a basic http.conf file:
sudo gedit /etc/apache2/httpd.conf
...add: "ServerName localhost"
Enable mod-rewrite
sudo a2enmod rewrite
Reload and restart Apache:
sudo /etc/init.d/apache2 reload
sudo /etc/init.d/apache2 restart

Create MySQL Database for Drupal Installation

Issue the following commands to create a new database:
mysql -u root -p
create database localhost_drupal7;
create user 'drupal7'@'localhost' identified by 'password';
grant all privileges on localhost_drupal7.* to drupal7@localhost;
quit
Generally, we'll use a revision system for our Drupal code. It's always a good idea to snap-shot our Database from time to time and before any major updates too. Below, is a simple script I use to accomplish this.
#!/bin/sh
if [ ! -d ~/backups ]; then
 mkdir ~/backups
fi
mysqldump -u root -p localhost_drupal7 > /tmp/localhost_drupal7.sql
cd ~/backups
tar --create --gzip --absolute-names --preserve-permissions --file=db-backup-localhost_drupal7-`date +"%b_%d_%Y_%r"`.tar.gz -C /tmp localhost_drupal7.sql

Setting up the PHP Mail Function

Install postfix, select "internet site" in the first screen and "localhost" as the site name:
sudo apt-get install postfix
Now install the required PHP components using PEAR:
sudo pear install mail
sudo pear install Net_SMTP
sudo pear install Auth_SASL
sudo pear install mail_mime

Install Drupal 7 with Drush from Git

Issue the following command to install Drupal with drush, note the version number:
cd ~/www
drush --package-handler=git_drupalorg --drupal-project-rename=localhost.drupal7 dl drupal-7.12

Create Drupal Site Configuration and Populate Database

Issue the following commands:
cd ~/www/localhost.drupal7
drush site-install standard --site-name="Local Drupal7" --site-mail=yourmail@email.com \
 --account-name=root --account-pass=password \
 --db-url=mysql://drupal7:password@localhost/localhost_drupal7 
Install Common Modules / Themes
drush dl views
drush dl cck
drush dl zen
drush dl devel
drush dl entity
drush dl ctools
Set permissions on the files folder:
cd ~/www/localhost.drupal7/sites/default
chmod 666 files
Test the install, open localhost.drupal7/admin/reports/status and login with "root" and "password".

Install Varnish

If we plan to use Varnish in our production environment, we'll need to install it in our dev box to test configurations and VCL scripts.
Varnish can run on any port, but if we want to use 80, we'll need to change Apache to use something else:
sudo gedit /etc/apache2/ports.conf
Change:
#NameVirtualHost *:8080
#Listen *:8080
We will also need to change port settings (<VirtualHost *:8080>) in the sites folder:
sudo gedit /etc/apache2/sites-available/localhost.drupal7
sudo gedit /etc/apache2/sites-available/default
Now we can install and configure Varnish:
sudo apt-get install varnish
Backup configuration files:
sudo cp /etc/varnish/default.vcl /etc/varnish/default_vcl.txt
sudo cp /etc/default/varnish /etc/default/varnish.txt
Create storage location:
sudo mkdir /var/lib/varnish/drupal7
sudo chown -R varnish.varnish /var/lib/varnish/drupal7
Modify the Varnish config:
sudo gedit /etc/default/varnish
Here's a sample configuration:
START=yes
INSTANCE=drupal7
DAEMON_OPTS="-a :80 \
-T localhost.drupal7:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-u varnish -g varnish \
-s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,250MB"
Create a VCL configuration:
sudo gedit /etc/varnish/default.vcl
Here's a sample:
backend default {
.host = "localhost.drupal7";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
} 
Restart Varnish:
sudo /etc/init.d/varnish restart
Test the configuration, open http://localhost.drupal7/.

Memcached Configuration

Installation Memcached & dependecies:
sudo apt-get install memcached libmemcached-dev php-pear php5-dev build-essential apache2-threaded-dev
Install Memcache PHP:
sudo pecl install memcache
sudo pecl install memcached
Add memcache extension:
cd /etc/php5/apache2/
sudo gedit php.ini
Add:
[memcache]
extension = memcache.so
extension = memcached.so
memcache.hash_strategy="consistent"
Restart apache:
sudo service apache2 restart
Run memcached on 127.0.0.0.1 with port 11211:
memcached -m 24 -p 11211 -d
We can create a short PHP script to test our installation, here's a sample:
sudo gedit /var/www/mctest.php
<?php
 $memcache = new Memcache;
 $memcache->addServer('127.0.0.1', 11211) or die ("Could not connect");
 $memcache->set('mytestvariable', "this is the data in my test variable", false, 60) or die ("Unable to save the data to the server");
 echo "Data has been stored in the cache";
 $result = $memcache->get('mytestvariable');
 echo "Retrieved data from the server:";
 var_dump($result);
?>
Test the configuration, open http://localhost/mctest.php.
Download Memcache Drupal 7 Modules:
cd ~/www/localhost.drupal7
drush dl memcache
You need to include and configure memcached files into settings.php. If you don't, you will get error kind like this : Fatal error: Class 'MemCacheDrupal' not found in /home/ubuntu/drupal7/includes/cache.inc on line 27 Call to undefined function dmemcache_stats() on line 118:
sudo gedit sites/default/settings.php
<?php
// Memcache ----
// the path to the core cache file
include_once('./includes/cache.inc');
// the path to the memcache cache file
include_once('./sites/all/modules/memcache/memcache.inc');
// make MemCacheDrupal the default cache class
$conf = array(
 'cache_default_class' => 'MemCacheDrupal',
 'memcache_servers' => array('127.0.0.1:11211' => 'default'),
 'memcache_bins' => array('cache' => 'default')
);
?>
Enable the memcache_admin module:
drush -y en memcache_admin
Add memcache to the command line php:
sudo gedit /etc/php5/cli/php.ini
[memcache]
extension=memcache.so

APC (Alternative PHP Cache) Installation

Issue the following command to install PHP APC:
sudo apt-get install php-apc
Restart Apache:
apache2ctl restart
Check that PHP can now see the APC extension:
php -m | grep apc
You should see a single line output with "apc".

Setup Solr

Install tomcat 6, libmysql and java:
sudo apt-get update && apt-get upgrade
sudo apt-get install tomcat6 tomcat6-admin tomcat6-common tomcat6-user tomcat6-docs tomcat6-examples
sudo apt-get install libmysql-java
Download Apache Solr:
cd ~/
wget -c http://apache.mirrors.pelicantech.com//lucene/solr/3.5.0/apache-solr-3.5.0.zip
unzip apache-solr-3.5.0.zip
sudo cp ~/apache-solr-3.5.0/dist/apache-solr-3.5.0.war /var/lib/tomcat6/webapps/solr.war
sudo cp -R ~/apache-solr-3.5.0/example/solr/ /var/lib/tomcat6/solr/
Create new Solr configuration in Tomcat6:
sudo gedit /etc/tomcat6/Catalina/localhost/solr.xml
<Context docBase="/var/lib/tomcat6/webapps/solr.war" debug="0" privileged="true" allowLinking="true" crossContext="true">
<Environment name="solr/home" type="java.lang.String" value="/var/lib/tomcat6/solr" override="true" />
</Context>
Install the Drupal Solr Module:
cd ~/www/localhost.drupal7
drush dl apachesolr
The module comes with some sample configurations, you might want to compare the differences in: /home/[user]/www/localhost.drupal7/sites/all/modules/apachesolr/solrconfig.xml & /var/lib/tomcat6/solr/conf/solrconfig.xml, and /home/[user]/www/localhost.drupal7/sites/all/modules/apachesolr/schema.xml & /var/lib/tomcat6/solr/conf/schema.xml

Backup solrconfig.xml /var/lib/tomcat6/solr/conf/
cd ~/www/localhost.drupal7/sites/all/modules/apachesolr/solr-conf
sudo cp /var/lib/tomcat6/solr/conf/schema.xml schema_xml.bk
sudo cp /var/lib/tomcat6/solr/conf/solrconfig.xml solrconfig.xml.bk
Copy configuration files included in the Drupal Solr module
sudo cp schema.xml /var/lib/tomcat6/solr/conf/
sudo cp solrconfig.xml /var/lib/tomcat6/solr/conf/
Create a data folder and change solrconfig.xml in /var/lib/tomcat6/solr/
cd /var/lib/tomcat6/solr/
sudo mkdir data
sudo chown -R tomcat6:tomcat6 /var/lib/tomcat6/solr/data/
Assign the data folder in the solrconfig file
cd /var/lib/tomcat6/solr/
sudo gedit conf/solrconfig.xml
modify:
<dataDir>/var/lib/tomcat6/solr/data</dataDir>
If you followed the steps above for Varnish, Apache is already on 8080, so we'll need to change the port.
cd /var/lib/tomcat6/conf
sudo gedit server.xml
Setup and enable solr modules in Drupal
cd ~/www/localhost.drupal7
drush enable apachesolr apachesolr_search search cacherouter
drush vset --yes apachesolr_port 8080
drush vset --yes apachesolr_cron_limit 50
drush vset --yes apachesolr_search_make_default 1
drush vset --yes apachesolr_search_spellcheck 1
#Number of items to index per cron run:
drush vset --yes search_cron_limit 50
Restart tomcat
sudo /etc/init.d/tomcat6 restart
Test the installation by opening http://localhost:8081/solr/admin/

Setup Eclipse and xDebug

Download and install Eclipse:
I like to separate out my Eclipse instances depending on their purpose; for example, one for PHP another for Python, etc. The process described here is prepared with that in mind, I'll include a script written written by a friend of mine that will make this very easy to do.
cd /tmp
wget http://carroll.aset.psu.edu/pub/eclipse/eclipse/downloads/drops/R-3.7.1-201109091335/eclipse-SDK-3.7.1-linux-gtk.tar.gz
tar zxvf eclipse-SDK-3.7.1-linux-gtk.tar.gz
sudo mkdir /opt/conjunction
sudo mkdir /opt/conjunction/php
sudo mv /tmp/eclipse /opt/conjunction/php
EditBox can be very helpful in navigating the array structures in Drupal, to install it:
cd '/opt/conjunction/php/eclipse/plugins/'
wget http://iweb.dl.sourceforge.net/project/editbox/plugin/alpha/pm.eclipse.editbox_0.0.22.jar
The following script will help isolate your environments:
#!/bin/bash

prog="$0"

if [ -n "$1" ]
then
    selection="$1"
else
    echo "usage: "`basename "$prog"`" eclipse_configuration"
fi

eclipse_command="/opt/conjunction/${selection}/eclipse/eclipse"
if [ ! -x "${eclipse_command}" ]
then
    echo `basename "$prog"`": cannot find ${selection}"
    exit 1
fi

eclipse_configuration="${HOME}/.conjunction/${selection}/config"
if [ ! -d "${eclipse_configuration}" ]
then
    if [ -e "${eclipse_configuration}" ]
    then
        echo `basename "$prog"`": cannot create configuration directory ${eclipse_configuration}"
        exit 1
    else
        mkdir -p "${eclipse_configuration}"
    fi
    if [ ! -d "${eclipse_configuration}" ]
    then
        echo `basename "$prog"`": failed to create configuration directory ${eclipse_configuration}"
    fi
fi


eclipse_data="${HOME}/conjunction/${selection}"
if [ ! -d "${eclipse_data}" ]
then
    if [ -e "${eclipse_data}" ]
    then
        echo `basename "$prog"`": cannot create data directory ${eclipse_data}"
        exit 1
    else
        mkdir -p "${eclipse_data}"
    fi
    if [ ! -d "${eclipse_data}" ]
    then
        echo `basename "$prog"`": failed to create data directory ${eclipse_data}"
    fi
fi

# start the appropriate eclipse
exec "${eclipse_command}" -configuration "${eclipse_configuration}" -data "${eclipse_data}"
Open eclipse with, adding the name (location) of the environment:
./run_eclipse.sh php
Install PHP Development Tools (PDT):

Launch Eclipse and navigate to Help->Install new Software
Add the Indigo update site ‘http://download.eclipse.org/releases/indigo’. This will take sometime to add, let it go for 5 or so minutes.
Once the Indigo Update Site is added, add the PDT 3.0 Update Site http://download.eclipse.org/tools/pdt/updates/3.0/milestones/

Now, to install simply select PDT Development Tools All in One SDK (leave the others unselected) and click next. The installation process shouldn’t take more than a few minutes.

Configure Eclipse for Drupal:
Make sure Drupal file types are recognized as PHP files:
Window->Preferences
Expand the left-hand menu to General -> Content Types.
Under Content types on the right, click Text -> PHP Content Type.
Add the *.engine, *.theme, *.install, *.inc, *.module *.profile and *.test file types

Make sure the file encoding and characters are Unix friendly so that any code can be committed back in to the Drupal repositories.
Window -> Preferences
In the left-hand menu click on General -> Workspace: Check Text file encoding and select
Other : UTF-8 Check New text file line delimiter and select
Other:
Unix Ensure that spaces are used instead of tabs:
Window -> Preferences
the left-hand menu click on General -> Editors -> Text
Editors: Check Insert spaces for tabs.
In the left-hand menu click on PHP -> Code Style ->
Formatter: Set Tab policy: Spaces. Set Indentation size to 2.
Setting up project
File-> New -> Other
PHP Project
Create project from existing location
/home/[user]/www/localhost.drupal7
Title the project and select Finish.

Installing XDebug

There's already a package with a version of XDebug compiled especially for Ubuntu, however this does not allow you to see all the variables in the current scope, so we will want to download and compile this for ourselves:
cd ~
wget http://www.xdebug.org/files/xdebug-2.1.2.tgz
tar zxvf xdebug-2.1.2.tgz
cd xdebug-2.1.2
phpize
./configure --enable-xdebug
make
#This will produce a file called xdebug.so in the modules directory, so now we'll just copy this to the appropriate path (ls -al /usr/lib/php5/)
sudo cp modules/xdebug.so /usr/lib/php5/20090626+lfs/
sudo chmod 644 /usr/lib/php5/20090626+lfs/xdebug.so
Now, edit Apache's copy of your php.ini file, which is usually at /etc/php5/apache2/php.ini.
sudo gedit /etc/php5/apache2/php.ini
#for the command line php:
sudo gedit /etc/php5/cli/php.ini
Add this section at the bottom:
[xdebug]
xdebug.remote_enable=1
xdebug.remote_host="localhost"
xdebug.remote_port=9000
xdebug.remote_handler="dbgp"
zend_extension=/usr/lib/php5/20090626+lfs/xdebug.so
Restart Apache
sudo /etc/init.d/apache2 restart
You can use the following PHP script to test the installation:
sudo gedit xdebug.php
<?php
$address = '127.0.0.1';
$port = 9000;
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($sock, $address, $port) or die('Unable to bind');
socket_listen($sock);
$client = socket_accept($sock);
echo "connection established: $client";
socket_close($client);
socket_close($sock);
?>
Configure xDebug in eclipse
./run_eclipse.sh php
Make sure your project is open and ready to work with. Right-click and choose Debug As -> Debug configurations. You will need one debug configuration for each of your Eclipse projects.

In the left pane you will see a load of options. We need PHP Web Page, so double-click this to create a new entry underneath. Give it a name, which can be the same name as your project. Change the debugger to XDebug.

Use default web server for localhost, or change to localhost.drupal7

Syslog

Install & configure the Syslog module
cd ~/www/localhost.drupal7
drush en syslog
Configure rsyslog to Log to a Separate File
# drupal loging
if ($programname == 'drupal') and ($syslogseverity <= '6') and ($msg contains 'localhost.drupal7') then /var/log/websites/localhost.drupal7.log
Add the above to /etc/rsyslog.d/drupal.conf and restart rsyslog.
mkdir /var/log/websites
sudo vi /etc/rsyslog.d/drupal.conf
sudo service rsyslog restart
Open /etc/rsyslog.conf and make sure the file is included
$IncludeConfig /etc/rsyslog.d/*.conf
Open http://localhost.drupal7/admin/config/development/logging and set the Syslog Identity to match the programname value we used above, in this case, "drupal". Using the rsyslog filter we're using, it does not matter which facility we send to. Save the configuration.
Try adding the following code somewhere to test this functionality:
<?php  watchdog('type, 'message');  ?>
Typically, you will use this in failure situation, for example:
<?php  
try {
   module_invoke_all('cron');
} catch (Exception $e) {
  watchdog('cron', t('cron failed because ' . $e->getMessage()), WATCHDOG_ERROR);
}
?>

Tags: