Some users, especially those lacking in technical proficiency, may prefer to use an already built appliance rather than rolling their own from scratch.

With some scripting on Ubuntu 8.10 (Intrepid Ibex) we can build fully customized Drupal LAMP development servers, as virtual appliance to VMware, or to other virtualization environments like XEN or KVM. In this how-to you can learn show how to use this method to have various development or test servers in one hardware box running Ubuntu 8.10 and VMware Server 2.0.

You need a machine with Ubuntu 8.10 (Intrepid Ibex) and VMware Server 2.0, as host system to the appliances. VMware Server 2.0 install on Ubuntu 8.10. can be learned here or here. We will need free IP addresses for the virtual machines, so you will need a properly configured DHCP server or a router, as well.

vmbuilder
The magic happens with vmbuilder, a tool introduced in Ubuntu 8.10, and targeted to build virtual machines with Ubuntu as operating system for multiple virtualization environments. Currently it supports Xen, KVM, VMware Workstation 6, and VMware Server. In the following, we are going to create virtual appliances to VMware Server.

To install vmbuilder, type:
sudo apt-get install python-vm-builder

To learn the parameters for Ubuntu and VMware Server, type:
sudo vmbuilder vmserver ubuntu --help

Preparations
vmbuilder uses a configuration file to create virtual machines (/etc/vmbuilder/libvirt/) We create a copy and modify that one:

sudo mkdir /var/vm
cd /var/vm
sudo mkdir -p /var/vm/mytemplates/libvirt
sudo cp /etc/vmbuilder/libvirt/* /var/vm/mytemplates/libvirt/
sudo nano /var/vm/mytemplates/libvirt/libvirtxml.tmpl

Change the network section from

[...]
    <interface type='network'>
       <source network='default'/>
    </interface>
[...]

to

[...]
    <interface type='bridge'>
       <source bridge='br0'/>
    </interface>
[...]

because we want the VMs to use bridging in order to get to the network / Internet as a standalone server.

Defining the Drupal LAMP virtual machine
Defining a virtual machine with Ubuntu's vmbuilder is quite simple, there is set of command line parameters, but here we use a configuration file. So at the end, we'll create a Drupal LAMP server with Ubuntu for VMware with this simple command:
vmbuilder vmserver ubuntu -c lamp-vm.cfg

The content of lamp-vm.fg file is:

##
## config file for vmbuilder to build a LAMP server
##
## use: sudo vmbuilder vmserver ubuntu -c lamp-vm.cfg
##
## background: http://www.wepoca.net/doc/drupal-lamp-virtual-server
##
## created by doka@wepoca.net
##            2009-02-15
##            www.wepoca.net
##

[DEFAULT]
arch = i386
overwrite = true
tmpfs = -
firstboot = lamp-vm-boot.sh
firstlogin = lamp-vm-firstlogin.sh
templates = mytemplate
part = lamp-vm.partition
mem = 1024
hostname = lamptest
domain = local
ip = dhcp
user = doka
name = Doka
pass = wepoca

[ubuntu]
flavour = virtual
suite = intrepid
iso = /home/<YOURHOME>ubuntu-8.10-desktop-i386.iso
mirror = http://192.168.2.4:9999/ubuntu
components = main,universe,restricted,multiverse
addpkg = acpid, apache2, php5, php5-mysql, php5-gd, phpmyadmin, wget, nano, mysql-server

[vmserver]

Let's go through the parameters of lamp-vm.cfg:

  1. arch
  2. Specify the target architecture. arch = i386 means a 32 bit machine. If your virtual machine needs to use more than 3 GiB of ram, you should build a 64 bit machine (arch = amd64). Defaults to host arch.

  3. overwrite
  4. Force overwrite of destination directory if it already exist, default: False

  5. tmpfs
  6. Because writing to RAM is a LOT faster than writing to disk, if you have some free memory, let vmbuilder perform its operation in a RAMdisk. So tmpfs option will help you do just that: vmbuilder will be working in the RAM during install. Either specify its size or just "-" to use tmpfs default (suid,dev,size=1G).

  7. firstboot
  8. The first time the machine boots we'll need to install openssh-server so that the key generated for it is unique for each machine. We can also use this place to do other tasks, so we'll write a script called lamp-vm-boot.sh. See details at the lamp-vm-boot.sh section below. It is ran as root.

  9. firstlogin
  10. The first login script ,called lamp-vm-firstlogin.sh. Place for install tasks needing some user interaction during their setup, like setting MySQL root password, or keyboard preferences. See details at the lamp-vm-firstlogin.sh section below.

  11. templates
  12. Place of the modified libvirt templates, so mytemplates in our case.

  13. part
  14. Allows to specify a partition table in a separate text file, each line should specify the mountpoint and size, one per line, separated by space, where size is in megabytes. You can have up to 4 virtual disks, a new disk starts on a line containing only '---'. My lamp-vm.partition file looks like this, and results in two disks, the second one contains the /var

    root 2000
    swap 1000
    ---
    /var 1000
    
  15. mem
  16. Assign MEM megabytes of memory to the guest VM, default is 128MB. Given that RAM is much easier to allocate in a VM, memory size should be set to whatever you think is a safe minimum for your appliance.

  17. hostname
  18. Set as the hostname of the guest. Default:ubuntu. Also uses this name as the VM name.

  19. domain
  20. Set as the domain name of the guest. Default is the dot (.)

  21. ip
  22. IP address in dotted form [default: dhcp]. You'll need to set the usual networking parameters like gateway and mask, if you deviates from default. See the networking section in help (sudo vmbuilder vmserver ubuntu --help)

  23. user
  24. Username of initial user [default: ubuntu], with sudo rights on guest VM.

  25. name
  26. Full name of initial user [default: Ubuntu]

  27. pass
  28. Password of initial user [default: ubuntu]

  29. flavour
  30. Kernel flavour to use. Default and valid options depend on architecture and suite.

  31. suite
  32. Ubuntu suite to install. Valid options: dapper feisty gutsy hardy intrepid [default: intrepid]

  33. iso
  34. Use an iso image as the source for installation. Copy an iso image to your home, and change this line accordingly. Full path to the iso must be provided. It requires suite and kernel parameter to match what is available on the iso, obviously.

  35. mirror
  36. Use an Ubuntu mirror at URL instead of the default, which is http://archive.ubuntu.com/ubuntu. See details below.

  37. components
  38. A comma separated list of distro components to include (e.g. main,universe)

  39. addpkg
  40. Install PKG into the guest (can be specified multiple times). Used to list the components of the LAMP server.

lamp-vm-boot.sh: the booting script
In this script we set the locale to hu_HU, make update&upgrade in order to finish the installation, install the OpenSSH server, and clean up after install. Before use, you might want to set the locale to your preferences.

##
## This script will run the first time the virtual machine boots
## It is ran as root.
##
## before use: set LOCALE according to your preferences.
##
## use: called by lamp-vm.cfg
##      
##
## background: http://www.wepoca.net/doc/drupal-lamp-virtual-server
##
## created by doka@wepoca.net
##            2009-02-15
##            www.wepoca.net
##
echo ""
echo ""
echo "This script runs the first time the virtual machine boots"
echo ""
echo "1. Set locales and keyboad"
#
# give the opportunity to change the keyboard
# change the next line according to your preferences.  For English use LOCALE=en_US
#
LOCALE=en_US
#
#
cat /usr/share/i18n/SUPPORTED | grep $LOCALE > /var/lib/locales/supported.d/local
dpkg-reconfigure locales
update-locale LANG=$LOCALE.UTF-8

# update & upgrade
echo ""
echo "2. Update and upgrade Ubuntu"
apt-get update
apt-get upgrade

# Install openssh-server, can be left out
echo ""
echo "Install openssh-server"
apt-get install -qqy --force-yes openssh-server

# clean up
echo ""
echo "4. Clean up"
apt-get autoclean
apt-get autoremove

# display info for first login
#
# the first user from config file
USER=`ls /home | grep -v 'lost+found'`
#
# actual IP
IP=`ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1 }'`
#
echo ""
echo ""
echo "Your virtual machine has been booted!"
echo "Copy/paste next line into a terminal, and login to the new virtual machine!"
echo "ssh $USER@$IP"
echo ""

lamp-vm-firstlogin.sh: the first login script
In this login script we set the MySQL root password, download and prepare the Drupal source in the home of the first user, define a catch-all vhost config file for Drupal 6 in Apache, configure phpMyAdmin, increase the PHP memory limit to 64 MB, and prepare the MySQL to use Drupal.

##
## This script is ran the first time a user logs in
##
## use: called by lamp-vm.cfg
##      
##
## background: http://www.wepoca.net/doc/drupal-lamp-virtual-server
##
## created by doka@wepoca.net
##            2009-02-15
##            www.wepoca.net
##
## 
echo ""
echo ""
echo "This script runs the first time a user logs in"

#configure the mysql server root password
echo ""
echo "1. Setting the mysql server root password"
sudo dpkg-reconfigure mysql-server-5.0

#install and configure phpmyadmin
echo ""
echo "2. install and configure phpmyadmin"
sudo apt-get install phpmyadmin

#download and prepare Drupal source
echo ""
echo "3. Download and prepare the Drupal source"
VERSION="drupal-6.10"
echo "Please, enter the Drupal version! [$VERSION]"
read NEWVERSION
if [ "$NEWVERSION" = "" ]; then
  echo "using default $VERSION"
else
  VERSION=$NEWVERSION
  echo "using $VERSION"
fi

# install into the home of the first user
USER=`ls /home | grep -v 'lost+found'`
wget http://ftp.drupal.org/files/projects/$VERSION.tar.gz
tar -zxpf $VERSION.tar.gz
sudo mv $VERSION drupal6
sudo cp /home/$USER/drupal6/sites/default/default.settings.php /home/$USER/drupal6/sites/default/settings.php
sudo mkdir /home/$USER/drupal6/sites/default/files
sudo chmod a+w /home/$USER/drupal6/sites/default/files
sudo chmod a+w /home/$USER/drupal6/sites/default/settings.php

# some Apache modules for clean URLs and virtual hosts
echo ""
echo "4. Prepare Apache for Drupal"
sudo a2enmod vhost_alias
sudo a2enmod rewrite

# Drupal6 catch-all vhost config file
echo "
<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName d6
        ServerAlias d6 *.d6

        DocumentRoot /home/$USER/drupal6
        <Directory /home/$USER/drupal6/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        ErrorLog /var/log/apache2/error.log
        LogLevel warn
        CustomLog /var/log/apache2/access.log combined

</VirtualHost>
" >> ~/d6
sudo mv d6 /etc/apache2/sites-available/.
sudo a2ensite d6

# PHP memory increase to 64M
echo ""
echo "5. Prepare PHP for Drupal"
sudo sed -i 's/memory_limit = 16M/memory_limit = 64M/' /etc/php5/apache2/php.ini

# Apache needs to be restarted
echo ""
echo "6. restart Apache"
sudo /etc/init.d/apache2 restart

# Drupal user and database in MySQL 
echo ""
echo "7. Prepare MySQL for Drupal"
echo "Please, enter your MySQL root password!"
read PWD

DBU=drupaluser
echo "Please, enter the database user for Drupal [$DBU]"
read NEWDBU
if [ "$NEWDBU" = "" ]; then
  echo "using default $DBU"
else
  DBU=$NEWDBU
  echo "using $DBU"
fi
DBPWD=drupalpwd
echo "Please, enter the database user for Drupal [$DBPWD]"
read NEWDBPWD
if [ "$NEWDBPWD" = "" ]; then
  echo "using default $DBPWD"
else
  DBPWD=$NEWDBPWD
  echo "using $DBPWD"
fi
DB=drupaldb
echo "Please, enter the database user for Drupal [$DB]"
read NEWDB
if [ "$NEWDB" = "" ]; then
  echo "using default $DB"
else
  DB=$NEWDB
  echo "using $DB"
fi

mysql -uroot -p$PWD -e "CREATE DATABASE $DB CHARACTER SET 'utf8'"
mysql -uroot -p$PWD -e "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON $DB.* TO '$DBU'@'localhost' IDENTIFIED BY '$DBPWD'"
mysql -uroot -p$PWD -e "FLUSH PRIVILEGES"

# It's ready to use
IP=`ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1 }'`
echo ""
echo "Your appliance is now ready for Drupal!"
echo ""
echo "Use phpMyAdmin: http://$IP/phpmyadmin"
echo "Add this line to /etc/hosts file in your HOST: $IP YOURDOMAIN.d6"
echo "and type in your browser: http://YOURDOMAIN.d6"
echo ""

Accelerate the install process

  1. Using tmpfs
  2. tbd.

  3. Using Ubuntu local mirror
  4. tbd.

And putting all together
tbd.