Setting up a LAMP on a Virtual Box
An almost step-by-step tutorial

Fine tuning the environment

This is all good but too simple for an efficient development environment. We need IDEs, GUIs, tools, extensions etc.

Paths and folders

If you don’t want to waste any minute on find some important file or information on your environment it is recommended to specify them on your own.

DNSmasq and DHCP

Developers never satisfied with only one website. More websites mean more web roots. More web roots mean virtual hosts. The Apache allows us to create numerous separated websites run in parallel, on the same physical hardware.

Creating virtual hosts is not a spooky magical thing. Let's suppose that we work on the website, so it is logical that we name the development site something similar, e.g.:

To do that, first we have to cheat a bit, and we turn our VM into our own DNS and DHCP server. In the Terminal type the following:

$> sudo apt-get install dnsmasq dhcp3-server dhcp-client $> sudo apt-get install dnsmasq dhcp3-server dhcp3-client

Then edit the dnsmasq's config file. Like many other services on Linux, the dnsmasq supports to read related config files from a specified folder. It is good, when a new version comes out, so our setting won't be overwritten. So in the Terminal type:

$> sudo mcedit /etc/dnsmasq.d/localhost.conf

Look for the line starts with '#address=/' (with F7) and in a new line insert the following:

Simply insert the following:


Press F2 to save and F10 to exit. Now edit the DHCP client's config file:

$> sudo mcedit /etc/dhcp/dhclient.conf

Look for the line ';prepend domain-name-servers;' (with F7) and delete the leading semicolon to uncomment it.

Look for the line 'prepend domain-name-servers;' (with F7) and delete the leading comment charater (that is semicolon ';' or hashmark '#') to uncomment it.

prepend domain-name-servers;

This will make Ubuntu to look for any domain name on the local computer first so the dnsmasq will be able to catch the '*.localhost' domain requests (the rest will be skipped so the true DNS servers will handle them) and will redirect to where the Apache is ready route to the correct virtualhost. Got it?

Now (re)start the services:

$> sudo service dnsmasq restart $> sudo dhclient

Test it with ping any .localhost address you want:

$> ping –c 3 any.address.i.want.localhost

You should see something like this:

Check domain routing

If everything works well, you will never need to take care with domains again, only with web roots and virtual hosts.

Web roots and Virtual Hosts

Now it’s time to produce our development site. To create the we should do the following steps:

  1. create home folders

    Many websites use (and it is recommended to use) include folders outside of the document root, so we create ours to support this recommendation as well:

    $> mkdir /var/www/ $> mkdir /var/www/ $> mkdir /var/www/ $> touch /var/www/
  2. add some dummy content to index.html

    Edit the /var/www/ and add some content to it. 'Lorem ipsum' should do it for a while.

  3. define virtual host

    We’ve created include folder for the non-public script files, and a public folder for the document root.

    Now create the virtual host file:

    $> sudo mcedit /etc/apache2/sites-available/

    And in the editor type:

    <VirtualHost *:80> ServerName foo.localhost ServerAlias DocumentRoot /var/www/ <Directory /var/www/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny Allow from all </Directory> ErrorLog /var/log/apache2/ LogLevel warn CustomLog /var/log/apache2/ combined </VirtualHost>

    You might have noticed that we defined not only with 'www' part, but also without it. This brings the "simulation" a bit more close to reality.

  4. enable virtual host

    To enable this virtual host we need to create a symbolic link to the sites-enabled folder:

    $> sudo ln –s /etc/apache2/sites-available/ /etc/apache2/sites-enabled/
  5. restart web server

    If everything is OK (and it should be since I followed my own tutorial all the time) we can now reach the site with the dummy content.

    Virtual host is working!

To create another virtual host, simply repeat these five easy steps.

Common PHP third-party libraries

If you have two or more websites to develop, you probably use your good old scripting methods. You know them well and you can do your job faster with them. You probably also use third-party libraries like Smarty, or Zend Framework etc. But these libraries use too much disk space to place them into every project. So we have to create a common library folder and add to the PHP’s include path.

First create the folders:

$> sudo mkdir /var/wwwlib/ $> sudo mkdir /var/wwwlib/library $> sudo chown –R developer:developer /var/wwwlib

Then add to the PHP by editing the modules.ini file (if not exists then this command will also create it):

$> sudo mcedit /etc/php5/apache2/conf.d/modules.ini

And add the following line to the beginning:


Press F2 to save and F10 to exit.

Now we have to restart the web server again as always. To add new library just simply copy its “Library folder” to the /var/wwwlib. For example if you download the Zend Framework from and extract it to your home folder, only the ‘Zend’ folder should be copied:

$> cd $> wget $> mv ./44oedwv $> unzip $> cp –R ./ZendFramework-1.11.6-minimal/library /var/wwwlib $> ls –la /var/wwwlib/library/

And in our projects now we can use Zend Framework. Create a PHP file and add this content:

<?php require_once 'Zend/Version.php'; echo Zend_Version::VERSION;

Test it in the web browser.

Xdebug for PHP

Good to know what went wrong, doesn’t it? So let’s install xdebug! In the terminal type:

$> sudo apt-get install php-pear $> sudo pecl install xdebug $> sudo apt-get install php5-xdebug

When it’s done edit the xdebug.ini file:

$> sudo mcedit /etc/php5/apache2/conf.d/xdebug.ini

Add the following lines to the end:

[debug] ; General xdebug.collect_includes=1 xdebug.collect_params=1 xdebug.collect_return=1 xdebug.default_enable=1 xdebug.extended_info=1 xdebug.show_local_vars=0 xdebug.show_mem_delta=1 xdebug.max_nesting_level=100 xdebug.dump.SERVER=REMOTE_ADDR,REQUEST_METHOD xdebug.idekey=netbeans-xdebug ; Remote settings xdebug.remote_autostart=off xdebug.remote_enable=off xdebug.remote_handler=dbgp xdebug.remote_mode=req xdebug.remote_host=localhost xdebug.remote_port=9000 ; Trace options xdebug.auto_trace=0 xdebug.trace_format=1 xdebug.trace_options=0 xdebug.trace_output_dir=/var/wwwlib/trace xdebug.trace_output_name=crc32 ; Profiling xdebug.auto_profile=0 xdebug.auto_profile_mode=2 xdebug.profiler_append=0 xdebug.profiler_enable=0 xdebug.profiler_enable_trigger=0 xdebug.profiler_output_dir=/var/wwwlib/profiler xdebug.profiler_output_name=crc32

Press F2 to save and F10 to exit.

Before restarting the web server, we need to create the trace and profiler folders although they are both disabled by default.

In the terminal type:

$> mkdir /var/wwwlib/trace $> mkdir /var/wwwlib/profiler

Remember that you are already the owner of the wwwlib so you don’t have to sudo. Edit the test.php again (or create a new PHP file, e.g.: info.php) and change the code to:

<?php phpinfo(); ?>

Then restart the web server and check the result in the browser. Look for the xdebug module.

The xdebug is installed.


OK, you probably do this whole thing to have a development system separated from the OS you are playing on, browsing the Internet, handling you emails, watching movies etc. and you are the only one who will use it. So why do you even need to waste time Concurrent Versions? The answer is simple: it not only good for team work but also for a personal backup and file-history archive.

You can choose from many solutions: CVS, SVN, and Github. However Git is very popular nowadays, but I found it as an online-only system so I don't think it would be a good choice when you want to develop on a train in a tunnel in the Alps with no Wi-Fi.

So my recommendation is the Subversion or its shorter name: SVN.

To install SVN type the following in the Terminal:

$> sudo apt-get install ssh subversion libapache2-svn

Now we are ready to create our repositories. Every project has its own so we have to create a new one for as well. First we have to create the folder:

$> sudo mkdir /var/svn $> sudo chown -R developer:developer /var/svn

Now create the SVN repository and then import the into it:

$> svnadmin create /var/svn/repos $> svn import /var/www/ file:///var/svn/repos/foo/trunk -m "Initial import"

You should see the following:

Create SVN repository

Once your project is in repository it would be good to have its features. Unfortunately importing a project into the SVN does not mean the project itself become a "working copy".

That is why it is worth to import only a minimal copy of a project first (like above: two folders and one file) and then check out it to the web server root, and finally copy the entire project over it and commit.

But now we've made it a bit different, we should first delete the web server copy of the project and then check out from the repository:

$> rm -rf /var/www/ $> svn co file:///var/svn/repos/foo/trunk /var/www/ Checkout the project

If you would like to use revision tagging (auto-props), type the following in the Terminal:

$> sudo mcedit /etc/subversion/config

And in the editor look for the line "#enable-auto-props = yes" and take out the '#' to uncomment the option and then add the following lines to the end of the file:

*.php = svn:keywords=Revision Id *.css = svn:keywords=Revision Id *.js = svn:keywords=Revision Id

And now you can use this tagging comment in PHP, CSS and JS files:

/** * @version $Id$ */

And after you commit the file, it would become something like this:

The auto-props

To make it work on files which are already committed (if $Id$ was represented in them before the auto-props option turned on), do the following:

$> cd /var/www/ $> find . \(-name "*.php" \) -exec svn propset svn:keywords Id {} \; $> find . \(-name "*.css" \) -exec svn propset svn:keywords Id {} \; $> find . \(-name "*.js" \) -exec svn propset svn:keywords Id {} \; $> svn ci -m ""