PHP developer living in Worthing, UK working for D3R. Starting Android / Java development for fun.
The purpose of this blog post is to get you running a reliable, Unix-based web development environment on top of Windows 7, using Virtuabox to create an Ubuntu virtual machine. It's an improvement on my previous setup, serves as a "note-to-self" on how to get up and running and is something I thought others would find useful.
Create a new VM and install Ubuntu. Install aptitude, then virtualbox guest utils:
sudo apt-get install aptitude sudo aptitude install virtualbox-ose-guest-utils
Restart your VM. If you like, you can shut down then enable 3D Acceleration in your VM's settings before restarting. Depends if you care about having hardware accelleration - useful if you want to use Unity.
If you're running on a Laptop or don't have much RAM, I'd recommend Fluxbox to keep bloat to a minumum. So, optionally, install that:
sudo aptitude install fluxbox
If you do run that, you'll need to log out, click your username, choose fluxbox, then log back in.
Once you're back in, it'll all be listening to your clipboard, screen resizing, etc thanks to the guest additions. If you did the 3D hardware thing you'll have Unity too. Now install Apache, PHP, mod-php, Mysql, PHP-Mysql, Curl, so on. Here's a glorious one-liner to do just that.
sudo aptitude install apache2 php5 libapache2-mod-php5 php5-cli php5-curl mysql-server php5-mysql libapache2-mod-auth-mysql phpmyadmin
Note: To save you frustration, when it comes to the "Configuring phpmyadmin" step and it asks you which web server to reconfigure automatically, apache2 is not selected by default even if it looks like it is. I'm looking at you, Vic. Hit space to put an asterisk in the apache2 box, then press enter.
Another note: for some stupid reason, by default, every /javascript directory is aliased. run `sudo rm -f /etc/apache2/conf.d/javascript-common.conf` to fix that.
Now restart apache2:
sudo /etc/init.d/apache2 restart
Open Firefox in your VM and visit "http://localhost/phpmyadmin". If all's well, you'll see "It works!". Visit "http://localhost/phpmyadmin" and, if all is well, you will see phpmyadmin.
Your virtual machine can probably already see the internet. That'll be using NAT. You have two options now if you want to have your Windows machine see your VM. Read the description of each then choose wisely.
Option one: Set up a Bridged Network with a permanent IP address
This the simplest way to get going. If your computer only ever lives on one network (i.e., it is a desktop), and you are able to set up a static IP, and your Windows machine has a static IP too, I recommend this.
Shut down your VM, open it's settings, under Network change Adapter 1 from NAT to Bridged Network. Press OK, then start up your VM. Check the internet's working.Presuming it is all working, go to terminal and type ifconfig. Keep that info up. Now go to network settings (if you're using Unity and are confused - hit the "windows key" and start typing to find stuff). Edit Auto eth0, change IPv4 Settings -> Method to Manual. Your "inet addr" was listed by ifconfig - put that as your address, you'll see your Mask from ifconfig to put in Netmask, and your Gateway is whatever your router's IP address is (e.g. 192.168.1.1). You will probably want to put your router's IP in the "DNS servers" box and the "search domains" box, unless you know otherwise.
Hit save, and if all is good, the internet should still work. If not, double-check your router's IP and make sure you put it as the Gateway, in DNS servers and in search domains. So now you have a virtual machine with a permanent IP on your network. Visit your VM's IP address, which you just set up, in your Windows machine and you should see the "It works!" message.
Option two: Set up a Host-Only Network
This option is best if you are constantly switching between networks, routers, or you otherwise don't want to give your VM a static IP address on your local network. It is, however, problematic. You may have noticed Virtualbox install a virtual network adapter on your Windows machine. This method makes use of that to set up a network between your Windows machine and your Ubuntu VM.
Shut down your VM, open it's settings, under Network go to Adapter 2. Enable it and choose Host-only Adapter, then click OK. Now start your VM. Once you're in, check the internet's working.
In terminal, type ifconfig. You'll see "eth0", which is your NAT network adapter, and you'll see "eth1", which is your Host-only Adapter. Note the IP address. Unless you are running multiple VMs that IP is safe enough to be considered permanent, however if you want to be sure, you are more than welcome to follow option one from paragraph three to set it up a permanent IP, with the exception you will be dealing with eth1, not eth0.
Enter the eth1 IP address in your Windows VM and you should see the "It works!" page.
Troubleshooting: If you have problems with the Virtualbox Host-Only Network
If you have problems, firstly upgrade Virtualbox. If you still have problems, make sure the latest virtualbox host-only network driver is installed - use Device Manager (in Windows) to find the virtual device, right click it, and click 'upgrade driver'. Select the Oracle/Sun Virtualbox directory in Program files and let it search there for a compatible driver. Once installed, try again.
If you still have problems, Windows might be refusing to do things on the basis the host-only network is "unidentified" and thus is forcing you to use your public firewall rules. To fix, you could go to start -> run -> secpol.msc. Click Network List Manager Policies, then double click Unidentified Networks, and check the circle to have unidentified networks always classed as private. This will make unidentified networks use your private firewall rules, which will likely be a be more relaxed ruleset.
So... now your VM is set up, sees the internet, and one way or another you have a solid IP address to reference your VM. At this point, make sure you can definitely see the "It works!" page from Windows. Now Ubuntu just needs to be serving files from your Windows machine as if it were on the VM.
You might be tempted to use Virtualbox's shared folders feature. Don't. It doesn't seem to support mmap properly - so the guest OS won't load changed files into it's cache, meaning you have to either specify `EnableMMAP Off` in your Apache config (and in anything else that might use it), or keep dropping the disk cache when you make tweaks to certain files (`echo 3 > /proc/sys/vm/drop_caches` as root).
So on with Samba.
Create a share on your Windows machine. I'm sharing C:\development. Right-click the development directory, go to Sharing, click "Share...", select Everyone from the drop-down, click Add, change Everyone's permission level to Read/Write, then click Share.
Note the Network Path - in my case, \\CRAIG-PC\development. Now, your IP on your host-only network adapter is probably 192.168.56.1. You can check by running ipconfig from the Windows command line. So for me, I will eventually be mounting //192.168.56.1/development.
Go to Control Panel, Network and Sharing Center, then click Change advanced sharing settings. Make sure file and printer sharing is turned on, public folder sharing is turned on and depending whether you want authentication you may want to disable Password protected sharing. For the purposes of this tutorial I will be using a username and password, for which I have a specially created "share" user on my Windows machine.
Okay, in your Ubuntu VM, open nautilus (the file browser), click on Network, find your PC (mine is called "CRAIG-PC") and browse your way to the network share you just created. You should be able to browse the network share as easily as that - although you may need to enter your username/password.
Now install smbfs:
sudo aptitude install smbfs
Let's test you can mount properly from the shell. Make sure you've unmounted the network share in Nautilus. Enter in terminal:
sudo mkdir /mnt/test sudo mount -t cifs //192.168.56.1/development -o username=your_user,password=your_password /mnt/test cd /mnt/test ls -l
And there you should get the contents of your C:\development directory. Hopefully that all worked out for you! Now, to make things a bit more permanent...
Unmount your test mount (I'm not going to tell you to delete your /mnt/test directory as you could delete stuff from your Windows drive if you aren't careful enough. I'll leave that up to you):
sudo umount /mnt/test
Install autofs:
sudo aptitude install autofs
Make a 'win' dir, or whatever else you fancy:
sudo mkdir /win
Edit /etc/auto.master (`sudo nano /etc/auto.master`) and add the following at the end of the file:
/win /etc/auto.win --timeout=300
Create an auto.win file in /etc/auto.win by running (`sudo nano /etc/auto.win`) and paste the following contents:
development -fstype=cifs,username=your_username,password=your_password,uid=1000,gid=1000 ://192.168.56.1/development
Restart autofs:
sudo service autofs restart
Now, autofs is quite magical. It doesn't mount something until it is actually needed. Also, note the --timeout=300? That means after five minutes of non-use, it will be unmounted automatically too. Try the following:
ls -l \win
Note there's nothing there? Now try this:
cd \win\development ls -l
Hopefully, that worked, and it just mounted itself. Pretty cool huh. It'll unmount after the timeout period. So we've avoided putting stuff in /etc/fstab, which means boot shouldn't hang, and when apache2 tries access the directory (which, to be honest, is probably going to be during boot) only then will it be mounted.
So from here on, it's up to you how you proceed.
Recommended reading: http://www.greenfly.org/tips/autofs.html
Comments 4 Comments
Just a minor note, your last 2 commands should be using forward slashes:
ls -l /win
cd /win/development
In a nutshell, this means e.g. any PHP scripts that need to write to the local filesystem will fail, such as my stupid counter script that I was testing stuff with:
<?php
$current = (int) file_get_contents('counter.dat');
$new = $current + 1;
file_put_contents('counter.dat', $new);
echo $new;
?>
For now I've gone with the VB shared folders way, despite your warnings. :|
So I decided to try harder with the Samba setup described here, and found a workable way to solve the permissions issue, which is simply to pass the "noperm" option (described on the page I linked in my previous comment), which entirely bypasses file permission checking on the client (i.e. the Ubuntu guest OS). If I knew more about network administration, I'm sure I could solve it more correctly, but for a little closed-box dev setup this seems fine to me.
When using the mount command, change this line:
sudo mount -t cifs //192.168.56.1/development -o username=your_user,password=your_password /mnt/test
to this:
sudo mount -t cifs //192.168.56.1/development -o username=your_user,password=your_password,noperm /mnt/test
When using autofs, change this line from /etc/auto.win:
development -fstype=cifs,username=your_username,password=your_password,uid=1000,gid=1000 ://192.168.56.1/development
to this:
development -fstype=cifs,username=your_username,password=your_password,uid=1000,gid=1000,noperm ://192.168.56.1/development
You can also pass the option file_mode=0777 which pretty much amounts to the same thing.
Something else I noticed while following through these instructions again is that, if you're using bridged networking (as recommended) instead of a host-only adapter, "192.168.56.1" won't be the address you want to use in the lines above, but rather whatever static IP you gave your host computer - in my case, 192.168.2.101.
Hope this is helpful to someone. :)