Introduction
I’ve been developing websites on my Windows PC for several years, using Apache, PHP, and MySQL. Yet my work is nearly always deployed on a LAMP stack. The fact that I work on Windows isn’t really a problem, but it’s not optimal either…
Common wisdom is that you should develop and test in an environment as similar as possible to the deployment setup. Windows is different from Linux in a number of ways, most noticeably in the way of user and file permissions. Another point is that a number of open source web development tools were initially created for Linux, and tend to be more optimized for that platform. Finally, running the server software directly on Windows involves some overhead, which isn’t necessary if you are not currently working on web projects.
One way to avoid these issues is to run a Linux operating system in a virtual machine, using it as a virtual server for hosting your works-in-progress. The virtual server can be set up and configured in any way you like, without affecting your host operating system.
Some context for this article: my primary system is a desktop PC, running Windows 7. I’ll be using VirtualBox to handle the virtualization, and the latest version of Ubuntu (currently 10.04) for the virtual server.
Before starting, you should have at least a basic understanding of using a Linux operating system. You should know about using the console, creating and editing files, and installing and configuring packages. I’m using Ubuntu, so any instructions will be based on that OS, though for the most part they will apply to other Linux systems.
At the end of this process, you will be able to install and run a virtual server, add and configure a selection of packages, and host your development websites. You will be able to SSH into your virtual server, upload files to it, and view your development sites from the host system.
Creating a virtual machine
First off, you’ll want to download a Linux distribution of your choice – a server version is ideal since it will be more server-oriented than a desktop version. I used the latest Ubuntu Server (10.04). Download the ISO to a convenient location on your computer.
Next, get yourself the latest version of VirtualBox (formerly provided by Sun, now by Oracle). The current version, as of this writing, is 3.2.6. Installation is quite simple – just run the installer and follow the prompts.
Once installation is complete, run the VirtualBox application. You’ll see a window like the following:

To create a virtual machine, click the New button near the top left corner.

The wizard is fairly simple. Start off by entering a name for the VM, and choosing the appropriate operating system. The default settings in the remaining steps are fine to use, so just click through. Once the wizard is complete, the main VirtualBox window will update:

Click the Settings button, located next to the New button. Select Storage on the left side of the new window. Click on Empty in the middle, then the folder icon on the right. You’ll enter the Virtual Media Manager. This is where you connect the downloaded ISO to the VM for installation. Click the Add button, navigate to where you saved the downloaded ISO, select it, and click Open. Click Select to get back to the Settings window – notice the change that indicates an associated ISO:

The configuration is done. You can click OK to return to the VirtualBox main window. It’s now time to install Ubuntu.
Installing Ubuntu Server
Above the VM listed in the VirtualBox window, click Start. A new window will open, showing the installation process.
For the most part, stepping through installation is pretty easy. Don’t do this if you are in a hurry, though, as it will take a little while.
There will be gaps between prompts where the installer does its work. Then there will be a few prompts for information, and the installer will go back to work.
For the most part, useful default values are in place. I’ll remark on some things you may want to change.
Enter a hostname – just to identify the system, has no relevance to sites being hosted. I used lampdev.
Select your time zone.
Partitioning – for a virtual dev server, Use Entire Disk will work.
After this point, the actual installation will start. It’s a bare-bones setup, so it should take just a little while. Don’t walk away though, as there are some additional prompts before installation is complete.
Enter your initial username and password. If this were a production system, the password should be fairly strong; however, as this is a dev system for internal use, something easy will do.
You’ll be asked if you want security updates done automatically, or if you prefer applying them yourself. I chose the latter, as this is in part a learning process for me.
You can choose any additional software to be installed at this point. You could save some time again later by choosing the packages you know you will need, but, again, this is a learning process, so I will be doing these myself. I didn’t choose any additional packages at this point.
The installer will chug away for a while longer, and then will finish, prompting you to reboot. You should "eject" the ISO by clicking Devices -> CD/DVD -> [ISO file] in the top menu of the VM window. And then choose to reboot. This is to ensure that the installation does not get started up again after reboot.
I did so, and logged in. The first thing I did was to shut down the server with the following command:
sudo shutdown -hP now
I’ll explain this choice in the next section.
Snapshot
It’s a little odd, shutting down the virtual server as soon as it’s installed, isn’t it? I did it because I want to have VirtualBox take a snapshot of the fresh install, which I can revert back to later if I make some serious mistake. Remember, learning process – it’s a lot easier when there’s a safety net! VirtualBox can only make or revert snapshots when the virtual machine in question is fully shut down.
Back in VirtualBox, with the server shut down, select the VM on the left side, then on the right side click the Snapshots tab. Click the Take Snapshot button, assign the snapshot a label and a description if desired, and click OK.

Your VM will automatically switch to using that snapshot – the name of the snapshot will be listed next to the name of the VM in the left pane.

If ready to continue, just start the VM using that snapshot.
Update
With a fresh installation, it’s a good idea to immediately apply any available software updates. It’s pretty simple…start with the following command:
sudo apt-get update
This updates the distro’s package lists, and ensures that when you install applications, you get the latest versions.
Next:
sudo apt-get upgrade --show-upgraded
This results in any available updates being applied to your virtual dev system, with a listing of such.
Now it’s time to see about connecting to the server via SSH.
Connecting via SSH
Secure SHell (SSH) is a network protocol, commonly used for creating secure connections from one machine to another. To connect to the virtual server via SSH, the server needs to have some software installed to handle incoming connections. This can be done with the free OpenSSH server software:
sudo apt-get install openssh-server
Because the server is virtualized, VirtualBox needs to be instructed to pass certain connections through from the host machine to the VM. This is done by opening a command line window on the Windows host and navigating to C:\Program Files\Oracle\VirtualBox, which is where VirtualBox lives. Note that the Oracle bit will be Sun if you haven’t updated your VirtualBox recently.
In the command line window, run each of the following lines:
VBoxManage setextradata "guestname" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort" 2222
VBoxManage setextradata "guestname" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/GuestPort" 22
VBoxManage setextradata "guestname" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/Protocol" TCP
Replace the guestname bit with the name of your virtual system as shown in VirtualBox, keeping the quotes in place. It’s actually the same command each time, but with some variation in the last two parameters.
Don’t close the command window yet – you’ll need it again shortly.
The change having been made, the VM needs a hard shutdown for the changes to take effect:
sudo shutdown -hP now
Restart the VM – you do not need to log in via the VirtualBox window. Now open up an SSH terminal of your choice – I use Secure Shell Client. You’ll want to connect to localhost, port 2222, with the username and password you set during server installation. VirtualBox will see the request for port 2222, and per the earlier configuration, pass the connection to port 22 on the VM. You should now have an SSH connection to your virtual server.
This seems an odd way to do this configuration – one might expect to find these sort of options within the VirtualBox GUI.
Apache
Now it’s time to install and configure Apache. This step will take a little bit of work, but future steps should be simpler. First, the installation:
sudo apt-get install apache2 apache2-doc
Now, Apache normally listens on port 80. This would be fine if a test site were being accessed from the VM, but the VM is a headless server, and test sites would be accessed from the host system. This is enabled with a little more configuration similar to what was done for SSH.
Back in your Windows host, return to the VirtualBox folder in the command line window. Run each of the following lines, again substituting your VM name, and varying the last two parameters of each line:
VBoxManage setextradata "guestname" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/Apache/HostPort" 8888
VBoxManage setextradata "guestname" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/Apache/GuestPort" 80
VBoxManage setextradata "guestname" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/Apache/Protocol" TCP
Same as before, a hard stop is required:
sudo shutdown -hP now
Start the VM up again, and you should be able to open a browser on the host system, type in localhost:8888, and see the default Apache localhost on the server.
Getting the standard localhost working is a good start, but chances are you want to be able to handle multiple sites, which doesn’t work so well on the lone localhost. You can create multiple virtual hosts, so each site you are running can have its own "host" and URL. With some configuration, Apache can handle this for you, and that is the next step.
A VHost
It’s time to create a virtual host. I’ll show how to do one now, and future ones can follow the same steps below.
I decided to set up a local copy of my personal site, grantpalin.com, for development purposes. The local copy will be set up for access at the grantpalin.com.dev URL. This is the example site I will use through this article; feel free to use the following code samples, substituting a site of your preference.
To start, create a new file in the Apache sites-available directory:
sudo touch /etc/apache2/sites-available/grantpalin.com.dev
Fill the file with the following:
<VirtualHost *:80>
ServerName grantpalin.com.dev
ServerAlias www.grantpalin.com.dev
DocumentRoot /srv/www/grantpalin.com.dev/public_html/
ErrorLog /srv/www/grantpalin.com.dev/logs/error.log
</VirtualHost>
This forms the essential configuration for a virtual host. Substitute the site name you wish to use – ensure you include the paths in your adjustments. You’ll note the reference to two different folders – public_html and logs – which need to be created in the correct places. You can save and close this file.
The website folders can be created via the following commands:
sudo mkdir -p /srv/www/grantpalin.com.dev/public_html
sudo mkdir /srv/www/grantpalin.com.dev/logs
The -p argument tells mkdir to create parent folders in the path if necessary. It is not needed on the second line since the appropriate parent folders will be in place. Replace grantpalin.com.dev with your site name; the paths should match those in the virtual host configuration.
With the site’s configuration created, and folders in place, the next step is to enable the site. That is done with the following command:
sudo a2ensite grantpalin.com.dev
Replace grantpalin.com.dev with your site name – it should match the ServerName defined in the virtual host configuration. The command essentially tells Apache that it may serve the site as configured. Note that a site can be disabled by using the a2dissite command.
With all the appropriate changes in place, you need to reload Apache; this needs to be done after any configuration changes, such as creating or editing virtual hosts. Here’s how to do it:
sudo /etc/init.d/apache2 reload
If any errors occur here, check your site configuration file, and ensure that the correct folder names are used.
There is one final step before accessing the virtual host. You must edit the hosts file on the host system, Windows in this case. The file is located – rather inconveniently, I’ll add – at C:\Windows\System32\drivers\etc\hosts. Just open it in a text editor, and add a line at the bottom:
127.0.0.1 grantpalin.com.dev
Save and close the file. You may need to take ownership of the file before being able to make any changes to it.
The added line tells the host OS to forward any requests for the given URL to localhost. The port is not included here, but if it is included when typing the URL in a browser, you’ll be able to visit the site you have set up. My URL was grantpalin.com.dev:8888.
PHP
Having done the legwork in setting up Apache, configuring it, and creating one or more virtual hosts, getting PHP working is a pretty simple matter.
Start off with running the following command:
sudo apt-get install libapache2-mod-php5 php5
libapache2-mod-php5 is the module for Apache that allows it to run PHP code, and php5 is obviously PHP itself.
There’s no special configuration to be done at this point, so just restart Apache to have it load the new module (modules are enabled when installed, but Apache still needs to be restarted):
sudo /etc/init.d/apache2 restart
Now to test it. Go into the site of your choice, assuming you set up at least one, and create a test file:
sudo touch /srv/www/grantpalin.com.dev/public_html/phptest.php
Edit the file to contain the following content:
<?php phpinfo(); ?>
You should be able to visit that page on the appropriate virtual host from your host system’s web browser. If the page works as expected, PHP is up and running.
If the file attempts to download instead of displaying, make sure you’re restarted Apache for the PHP module to work.
PHP offers a lot of configurability; I’ll run through some of the more useful options now.
Configuration
The PHP configuration files is located at /etc/php5/apache2/php.ini; open it in a text editor. I’ll point out some settings where the default values should be changed to help development efforts.
error_reporting = E_ALL | E_NOTICE | E_STRICT
Shows useful errors to help in developmentdisplay_errors = On
Shows errors on screen
There are many more options available, but those are enough to get started with.
MySQL
The last major step of this process is to set up a database server. To install MySQL, run the following command:
sudo apt-get install mysql-server
You will be prompted for the MySQL root password – for a purely development setup, I don’t see a need for a password, so I leave it blank. If you feel otherwise, you can provide a password of your choice.
To connect to MySQL from PHP, you need to install PHP’s MySQL driver:
sudo apt-get install php5-mysql
A simple way to test that MySQL is working is to create a small test page on one of the virtual hosts. Same as before, I dropped it in my first dev site:
sudo touch /srv/www/grantpalin.com.dev/public_html/mysqltest.php
Edit the file to contain something like the following:
<?php
//hostname or ip of server (for local dev server, localhost should work)
$server = 'localhost';
//username and password to log onto mysql
$user = 'root';
$pass = '';
//name of database
$name = 'mysql';
$conn = mysql_connect($server, $user, $pass) or die("<p>Failed to connect</p>");
echo "<p>Connection succeeded</p>";
mysql_select_db($name) or die("<p>Failed to select database</p>");
echo "<p>Database selection succeeded</p>";
//close connection
mysql_close($conn);
?>
If you view the test page in a web browser on your host system, and get a success message, then MySQL is installed and working, and PHP is able to connect to it.
What Next?
With the necessary infrastructure in place, you can begin hosting development sites in your VM. Take the time to define virtual hosts and create the appropriate directory structures that meet your needs. With whatever virtual hosts you need in place, you can use your SSH connection to piggyback a SFTP connection, and load the necessary files on each of your development sites.
Some FTP programs, including the FTP feature in Dreamweaver, allow you to transfer files over SFTP – this is usually an option that must be checked. Plain FTP is less secure, is ideally not used in production, and requires a separate server process. OpenSSH includes SFTP functionality out of the box.
There is another deployment option. You can base your test sites off source control checkouts, be they Subversion, Git, Mercurial, or whatever your pleasure is. You can even do work directly in the VM and commit your changes back to source control.
If you get the virtual server working just the way you like it, now could be a good time to take a snapshot of the current state in VirtualBox, so you can easily revert any future mistakes.
Conclusion
At this point, you have a virtual server set up and configured to suit development on the LAMP stack. You’re not limited to any of the individual components, of course; feel free to switch Apache for nginx or lighttpd, MySQL for PostgreSQL, or PHP for Perl, Python, or Ruby. It’s YOUR server, do whatever you like with it!
I have some ideas for additional posts on this track, so I may write more on the subject at a later time. Until then, happy coding.
Comments
Sorry, comments are closed.
Andrew Johns
September 8, 2010 @ 5:31 am
I’ve been setting up a virtual dev environment for PHP work using virtual box, with the addition of adding svn and cruisecontrol into the mix. I guess what I’m setting up really is a development environment and a build server all in one, so that when I commit any work, it’ll automatically build the project, and run unit tests to verify that everything still works.
I’ve got as far as installing the LAMP stack, and SVN, and cruisecontrol (with snapshots after each step!) but not actually set up any projects yet. I’m still half tempted to split my dev and build servers onto two virtual servers, or continue to do my dev work in windows before committing to the virtual server, but I’m not really sure yet.
Grant
September 11, 2010 @ 12:57 pm
It is a good idea to have your dev setup separate from the source/integration setup, so they can be managed independently. It’s a little more work, but it beats having a single catch-all setup, since both will have different requirements.
Trackbacks