Tag Archives: Coding

How to improve Symfony2 performance when running from shared folder on VM

Quite recently we, meaning PrepLounge, the startup I’m CTO at, got started on a new project and I chose Symfony as the framework to work with.

After reading the docs and running through the, fairly simply, install/setup steps I ran into a problem: Performance was really bad. A single request to the default controller (no changes where made to the AppBundle) took up to 8 seconds. This was unacceptable.

I googled about Symfony being slow and followed all the steps to improve the performance like:

  • Use bootstrap files
  • Enable APC for autoloading
  • Use composer’s class map functionality

Which is pretty much the same that’s listed on Symfony’s own site about performance improvements. And I even disabled Xdebug (on my dev system mind you, something unthinkable until now) in hopes that this might be the culprit. But all to no avail. Sure, every improvement shaved off a couple hundred milliseconds, but the best result I got was about 2 seconds per request. Which was still unacceptable.

I then dug deeper into the Symfony docs, trying to figure out how all the caching works and after reading how much file reading/writing is done for each request I started to suspect a completely different reason for the weak performance: My VM I use development.

My VM is a VirtualBox with Ubuntu 14.04 as guest system running on my MacBook Pro with OSX 10.11.1 as host. For all previous projects, the code always resided on the host and the VM gets access to it via shared folders.

And that’s exactly the problem. Apparently file reads/writes in shared folders are very slow compared to reads/write on the local file system. I had no idea. Sure, I figure there’d be some impact, but not that much.

Anyway, now that I had my suspicions I made some changes to my setup.

Previous setup:

  • Shared folder at /media/sf_project
  • Symlink from /media/sf_project to /opt/www/development/project
  • DocumentRoot at /opt/www/development/project/web

New setup

  • Shared folder at /media/sf_project
  • Actual copy of /media/sf_project at /opt/www/development/project
    • Updated every minute per rsync
  • DocumentRoot at /opt/www/development/project/web

And that did it!! Requests are blazing fast and take less than 100ms!

The only problem is, that the fastest a cronjob can run is once per minute. Which is probably fine in most cases, but for me as a developer to wait up to one minute for my changes to take effect is a nightmare! Especially when you are debugging or editing your CSS and only make small changes which you quickly want to check.

So I wrote a quick script that does exactly what the cronjob does: Run rsync to sync the folders and then set permissions. And then I updated the cron to run the script instead of having duplicate code. DRY ftw ;)

Here’s the script:

#!/bin/bash

if [ "$1" == "" ]; then
    echo "Syncing project files..."
    sudo rsync -rptz --stats --exclude 'app/logs/*' --exclude 'vendor/*' --exclude 'app/cache/*' /media/sf_project/* /opt/www/development/project
    sudo rsync -rptz --stats /opt/www/development/project/app/logs /media/sf_project
    sudo cp /opt/www/development/project/composer.json /media/sf_project
    sudo cp /opt/www/development/project/composer.lock /media/sf_project
    echo "Setting permissions..."
else
    sudo rsync -rptz --exclude 'app/logs/*' --exclude 'vendor/*' --exclude 'app/cache/*' /media/sf_project/* /opt/www/development/project
    sudo rsync -rptz /opt/www/development/project/app/logs /media/sf_project
    sudo cp /opt/www/development/project/composer.json /media/sf_project
    sudo cp /opt/www/development/project/composer.lock /media/sf_project
fi

sudo chown -R www-data:www-data /opt/www/development/project
sudo chmod -R 775 /opt/www/development/project

I called it “project-sync”, put it in /usr/local/bin and made it executable

sudo chmod +x /usr/local/bin/sync-project

Now, when calling it you can either simply use

project-sync silent

(actually any value as first parameter will trigger the silent mode) or, if you want more verbose output and info about what happend, simply run

project-sync

.

UPDATE:

I extended the cron to
a) ignore a couple of files I don’t need to copy since they don’t change locally (vendor, logs and cache files) and

b) sync a couple of files back into my local copy that I want to commit/need for debugging like composer-related files and the logs

I hope this is helpful to someone besides me :)

Dev-Box: Virtual Machines for Developers

This post goes out to all the coders using a Windows machine for development. Might be interesting for others aswell but I can’t say much about that as I’m a Windows user myself ;)

So what is this about? Well, some time ago I ran into smaller problems when trying to move a website from my local machine (which used XAMPP) to a real server (which was running on Ubuntu or some other Linux distro) and it was hard to fix the problems because of the differences between Windows and Linux servers.

I talked about this with a friend of mine and he told me about Virtual Machines (=VM). I had never heard of them before but what I heard was intriguing. Virtual Machines allow you to run a machine inside your machine, e.g. a Linux server inside your Windows machine. So you can use this VM with Linux to test your website locally before moving it to the real server. I know that no server is like the other and you might still run into some problems due to different library versions and so on, but you gotta admit that two Linux servers have way more in common than a Linux and a Windows server ;)

So in this post I’ll tell you how to setup your own VM with all the libs you need. Even if you haven’t worked with Linux before, you should be able to follow this tutorial/example easily.
Continue reading Dev-Box: Virtual Machines for Developers