Vagrant is a pretty nifty tool that simplifies developing on a Virtual Machine. However it is sometimes not obvious what happens in the background! An example of this is where your VM’s actually get downloaded to, and how they are managed.
Since Vagrant acts as a wrapper for VirtualBox (or VMWare Fusion more recently) when you “add” a box, it essentially downloads a pre-built Virtual Machine Disk (VMDK) from the internet/network and stores it somewhere. It then uses this as a base before applying your project-specific configuration, such as Shared Folders, networking and so on.
The VMDK’s get downloaded to a hidden sub-directory in your home directory.
Therefore if you run a command in your project (as per the tutorial) such as
vagrant box add precise32 \ http://files.vagrantup.com/precise32.box
Then assuming you are using VirtualBox (as boxes will be stored differently depending on which virtualization provider you are using) the box will be downloaded to the following location
If you look what is in there, you will see a VMDK, Vagrantfile describing the box, Open Virtualization Format (OVF) file for VirtualBox (so VirtualBox can import it, I assume you’ll get a VMX for VMWare Fusion) and a metadata JSON file telling Vagrant the provider (in this case VirtualBox)
ls Vagrantfile box-disk1.vmdk box.ovf metadata.json
In order to access certain aspects of a virtual machine in VirtualBox, you will need to install Guest Additions (similar to VMWare Tools I guess)
There is a manual page for installing Guest Additions but not all of it is self-explanatory…
First you need to log into your Linux virtual machine (VM) and install/configure x, y and z.
This part is relatively straightforward, just install using whatever package manager your Linux distribution has. The below example uses APT that comes with Debian-based distros:
sudo apt-get update sudo apt-get upgrade sudo apt-get install dkms
Where to find VBoxGuestAdditions.iso
Usefully Oracle don’t tell you in their guide, but it is available with the rest of the downloads at http://download.virtualbox.org/virtualbox/
So for example for version 4.1.6 the VBoxGuestAdditions_4.1.6.iso is located at http://download.virtualbox.org/virtualbox/4.1.6/VBoxGuestAdditions_4.1.6.iso
You need this image to install the VirtualBox Guest Additions themselves onto your VM, so you can either download it to your Linux VM and mount it there, or (which is what I did) download it to your Mac OS X host and mount it in the DVD drive using the VirtualBox Manager.
How to mount the image
You need to mount the image on the Linux VM, so that you can install VirtualBox Guest Additions from it. If you have mounted it in the VirtualBox Manager in the DVD drive then you will still need to mount it in the Linux VM; Since I can’t remember the last time I had to mount something in *nix from the command-line, here’s a quick way.
sudo mkdir /dev/dvd sudo mount /dev/dvd1 /mnt/dvd/ cd /mnt/dvd
Then you should see VBoxLinuxAdditions in that directory, which you need to run as per the manual. If the above doesn’t work it might be because your DVD drive in VirtualBox is called something else, like dvd (instead of dvd1) which probably differs depending on which distro you’re using.
Then you need to run the installer.
sudo sh ./VBoxLinuxAdditions.run
Once that’s done you can restart.
sudo reboot now
Everything should be finished now installation/configuration-wise, but you might encounter some problems… (otherwise skip to Mount the host folder)
Kernel header problems
I got some missing kernel header problems when trying to install Guest Additions, which if building the main Guest Additions module fails will be logged.
If you see something like this…
Error! Your kernel headers for kernel 2.6.35-28-generic cannot be found at /lib/modules/2.6.35-28-generic/build or /lib/modules/2.6.35-28-generic/source.
You can use the --kernelsourcedir option to tell DKMS where it's located, or you could install the linux-headers-2.6.35-28-generic package.
So you can do just that!
sudo apt-get install linux-headers-2.6.35-28-generic sudo ./VBoxLinuxAdditions.run
Hopefully this should install now (although the XFree86 bit will fail, assuming you’re using the command-line) and you may need to restart the VM, although I’m not sure.
Mount the host folder
You can create the host folder in the VirtualBox Manager in the Shared Folders tab on the Settings for that VM. If you add it on the command-line it’ll appear under the machine folders anyways. If you want to type it though, here’s what you’d type into the Mac OS X terminal (note this is the only thing that you’d type into the host itself)
VBoxManage sharedfolder add "my-ubuntu-vm" \ --name "websites" --hostpath "/Users/andrew/pizza"
To mount the Shared Folder from within the guest, the instructions from Ubuntu (as my guest is Ubuntu, although I think this is a better way to mount it anyways) were very useful.
sharename="whatever.you.want.to.call.it"; sudo mkdir /mnt/$sharename \ sudo chmod 777 /mnt/$sharename \ sudo mount -t vboxsf -o uid=1000,gid=1000 $sharename /mnt/$sharename \ ln -s /mnt/$sharename $HOME/Desktop/$sharename
Just change the target to be wherever you want the Shared Folder to be mounted in the guest. Now in theory if you go to that path in the guest, it should be the same as the directory you shared from the host!
If for some reason you’ve powered on and while Apache seems to be running OK, lighttp isn’t (for example phpMyAdmin isn’t working on localhost:10081/phpmyadmin) then you will need to start it manually. This is probably caused by a dirty restart, such as a power failure. On Mac OS X run this command…
sudo /usr/local/zend/bin/lighttpdctl.sh start
For Windows, I’m afraid I will have to find that out!
Sometimes if a Samba share (Windows share or a Samba share from Unix) does not disconnect cleanly in Mac OS X, you may end up with a broken symlink in /Volumes/
This means that even if you re-mount the same share, and it will be named the same in the Finder, the actual symlink path won’t be the same. For example if you’re using a Workspace in Eclipse that points to that share, you won’t be able to use it because /Volumes/ will look like this:
Andrew:Volumes andrew$ pwd /Volumes Andrew:Volumes andrew$ ls Macintosh HD share share-1
The old symlink will still be there, and it will create another one with a number appended. If this does happen, disconnect the Samba share from the Finder, then delete the remaining share from /Volumes/ and then re-mount it in the Finder.
The share should then mount with the correct path!
Unlike Windows which doesn’t come with Apache by default, or distributions of Linux which (usually) have their own package management systems, Mac OS X comes with an outdated version of Apache which isn’t handled by package management. This means it’s a pain to either update or remove it. Any Mac PHP developer will probably have tried MAMP which gives you a relatively pain-free installation, but for anything complex it can be a bit tricky due to the way it’s self-contained. As a Zend Framework developer I use Zend Server and Zend Server CE at work now and figured now that I’ve got to do some work at home I should look to get it installed and configured…
Just to check that everything is working OK to start with, go to http://localhost/ and you should see the default Mac OS X homepage which will be located in your Sites directory.
Disable the default Apache installation
Make sure you stop the default Mac OS X version of Apache before you start the new Zend one, or it’ll conflict.
Replace the default apachectl with Zend Server’s apachectl
Easiest way to do this (without uninstalling anything) is to replace the default apachectl with Zend Server’s apachectl, that way it will just appear to be launching Apache as per usual when OS X starts up.
Firstly move apachectl to a safe place, such as your home directory:
sudo mv /usr/sbin/apachectl /Users/yourusername/
Then create a symbolic link to Zend Server’s apachectl:
sudo ln -s /usr/local/zend/apache2/bin/apachectl /usr/sbin/
Start Zend Server’s Apache:
sudo apachectl start
You should then see:
/usr/sbin/apachectl start [OK]
This will indicate that you are running Zend Server’s Apache as opposed to Mac OS X’s Apache (as the latter doesn’t output to the terminal when you start/stop it) although if you go to http://localhost/ you will notice that you will get a 404.
Configure Apache to use port 80
I’m assuming to avoid any conflict with the default Apache installation that Zend Studio’s Apache comes preconfigured to use port 10088. To change this simply edit the configuration:
sudo vi /usr/local/zend/apache2/conf/httpd.conf
… or if you dont use Vi, use another text editor such as Nano:
sudo nano /usr/local/zend/apache2/conf/httpd.conf
Look for the line Listen 10088, then either comment it out and add a new line or edit the port to be port 80.
#Listen 10088 Listen 80
You may also need to change the DocumentRoot and first Directory parameters to your webroot (/Users/username/Sites for example)
Save httpd.conf (Ctrl + x in Nano to exit then y to save) and restart Apache:
sudo apachectl restart
If you go to http://localhost/ in your browser you should now see the default Mac OS X homepage, as httpd.conf should already be setup to point to your Sites directory by default.
If you get any complaints about the FQDN when you start Apache, such as:
httpd: Could not reliably determine the server's fully qualified domain name, \ using iMac.local for ServerName
Then you need to explicitely set the name of the domain to be used (in this case, localhost)
#ServerName www.example.com:10088 ServerName localhost:80
Configure Zend Framework
sudo ln -s /usr/local/zend/share/ZendFramework/bin/zf.sh ./zf
sudo ln -s /usr/local/zend/bin/pear ./ sudo pear upgrade pear
You can create symbolic links for the typical MySQL commands if you wish (although you can change the include paths for the shell if you so desire)
sudo ln -s /usr/local/zend/mysql/bin/mysql ./ sudo ln -s /usr/local/zend/mysql/bin/mysqladmin ./ sudo vi /usr/local/zend/mysql/data/my.cnf
You will then need to change where it looks for the socket:
#socket = /usr/local/zend/mysql/tmp/mysql.sock socket = /tmp/mysql.sock
If this doesn’t work (as it won’t for some programs) you will need to create a symbolic link for the socket:
sudo ln /usr/local/zend/mysql/tmp/mysql.sock /tmp/mysql.sock
If there isn’t a socket file there…
First symlink PECL
sudo ln /usr/local/zend/bin/pecl /usr/sbin/pecl
Then you will need to install Xdebug with it
sudo pecl update-channels
sudo pecl install xdebug
Errors installing via PECL
You might get an error with autoconf (I have Xcode 4.3 installed which might have something to do with it)
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.
ERROR: `phpize’ failed
If so you’ll need to either compile it yourself, or grab a pre-compiled version. Luckily the nice folks at ActiveState provide pre-compiled extensions. Grab the latest version from their site and copy the extension in the directory ’5.3′ (as in PHP 5.3)
cp xdebug.so /usr/local/zend/lib/php_extensions/
Configure Xdebug as a Zend Extension
You cannot enable Xdebug as a normal PHP extension as it won’t work properly; you need to enable it as a Zend extension. This means you’ll need to add the following line to php.ini
However this won’t work on it’s own as you will need to turn off the debugger that ships with Zend Server. The great instructions from the tailored installation instructions from Xdebug state “Open /usr/local/zend/etc/conf.d/debugger.ini and put a ; in front of the line that says zend_extension_manager.dir.debugger= so that it says ;zend_extension_manager.dir.debugger=”
If you have any problems configuring it, the Xdebug tailored instructions are a great help, just copy the HTML source of a phpinfo() script and it tells you what you need to do.
If you want to use Apache instead of Lighttp, you will have to create a Directory entry and Alias for phpMyAdmin:
sudo vi /usr/local/zend/apache2/conf/httpd.conf
Alias /phpMyAdmin /usr/local/zend/share/phpmyadmin <Directory "/usr/local/zend/share/phpmyadmin"> Options Indexes FollowSymLinks AllowOverride All Order allow,deny Allow from all </Directory>
sudo pear channel-discover pear.phpunit.de sudo pear channel-discover components.ez.no sudo pear channel-discover pear.symfony-project.com pear channel-discover pear.symfony.com sudo pear update-channels pear install pear.symfony.com/Yaml sudo pear install --alldeps phpunit/PHPUnit sudo ln -s /usr/local/zend/bin/phpunit ./
Whilst trying to figure out why Zend Server CE wasn’t working properly on my Mac (again…) I realised that something was wrong with the version of Apache shipped with OS X. Luckily Chris Oliver found the problem in the Apache control script.
It’d be nice if web stacks were as simple as on Linux (or even Windows) but you can but dream…
- The amount of overtime I'm doing at the moment is almost unbearable. Almost. Serves me right for the times I've said "it's almost OK now"
- RT @AlexBalfour2012: A mortgage broker just told me that if you have taken a payday loan (e.g. Wonga) in last 12 months most banks wont tou…
- "Dear other agency, can we have the SSL certificate you own for your client that we now have?" I'm sure this is going to go well...
- Just posted a photo http://t.co/5NC7JrmU9B
- Gorillaz #converse http://t.co/g8vBWosqSY
- PHP Startup: Unable to load dynamic library ‘/usr/lib64/php/modules/module.so’
- Concrete5 “Fatal error: Class ‘View’ not found”
- “Could not open configuration file /usr/local/zend/etc/sites.d/zend-default-vhost-80.conf”
- How to safely handle PHP “__toString() must not throw an exception”
- What does vagrant up do, where does the box get downloaded to?