Vagrant is an amazing tool for building development environments, and if you are not very familiar with it yet, I suggest you read my last 3 posts, which will guide you well into the Vagrant world.
A few months after I started playing around with Vagrant and Puppet, with smaller applications, I had the task to create a box for a Symfony app for the first time. I thought “all right, no problema! this will be a piece of cake, I already know the process, I just need to put it on puppet”. And of course I was wrong.
The Journey begins
After pain and suffering struggling with private repositories on Composer (a topic for another post), I could make the provisioning work fine, just to discover that the performance was horrible. At that point I was using a Macbook from the company I worked on, with modest 2 GB of ram. Then we started to try everything – NFS, more ram, and the final resource: vmware-fusion instead of Virtualbox. And it didn’t make much difference. Ok, it helped, decreasing the page load for around the half, but that was still too long – 6 to 8 seconds, still too much. Also, I didn’t want to use vmware at all.
Finding the problem
I always thought the problem with Virtualbox and NFS was the amount of files shared. So the vendor folder would be always a bottleneck – then I tried to move the vendor folder for inside the guest machine, for a non-shared location. It helped a little bit, but was impracticable, since we could not have access to the vendors through our Host machine IDE.
Then, recently, when I have already other Symfony apps to build boxes for (and I don’t even work at that company anymore), I read this excellent post from @beberlei and decided to give it a try. Basically speaking, the real problem regarding to performance on NFS shared folders are the I/O operations. So, to optimize your Box, you need to move your cache and logs folders to a location outside the synced folder. I did exactly what he proposed in his post, and below you can see a simple benchmark result:
There are some observations I would like to point: changing to NFS makes the first load takes more time (65 seconds in this test!), and this makes total sense based on @beberlei observations: anything that makes lots of writing on disk will be a bottleneck – Symfony caching in the first load is the main problem here. After the logs / cache dir optimization, the difference is really impressive as you can see in the last lines. Now you actually have a good use of NFS!
Vagrantee Symfony Sandbox
This is a Vagrant sandbox optimized for Symfony applications – implementing the changes to AppKernel proposed by @beberlei by applying a patch to the file (it will include 2 methods, getCacheDir() and getLogDir() – this is all you need basically) and using some puppet modules to make the provisioning easier and straightforward. I organised it in a way you can have multiple applications using the same box, changing between then through a shell script (vagrantee.sh). The Log / Cache dir change will only affect dev and test environments. Head to the Github repository: https://github.com/vagrantee/sandbox-symfony where you can find detailed usage instructions.