Search code examples
phpsymfonytwigvagrantnfs

Symfony2 and Twig performance in a vagrant box


Prerequisites:

  1. http://box.scotch.io/ vagrant box

  2. 2.
# -*- mode: ruby -*-
# vi: set ft=ruby :


Vagrant.configure("2") do |config|

  config.vm.box = "scotch/box"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.network "forwarded_port", guest: 80, host: 80
  config.vm.network "forwarded_port", guest: 3306, host: 3306
  config.vm.network "forwarded_port", guest: 443, host: 443
  config.vm.network "forwarded_port", guest: 1081, host: 1081
  config.vm.hostname = "scotchbox"
  config.vm.synced_folder "../../../project", "/var/www", :mount_options => ["dmode=777", "fmode=666", "uid=1000", "gid=1000"], type: "nfs"
  #config.vm.synced_folder "./mysql", "/var/lib/mysql", :mount_options => ["dmode=700", "fmode=600", "uid=106", "gid=112"], type: "nfs"
  config.vm.synced_folder "../../../project/_conf", "/etc/apache2/sites-enabled", :mount_options => ["dmode=755", "fmode=644", "uid=0", "gid=0"], type: "nfs"

#############################


$script = <<SCRIPT
  sudo service apache2 restart && sudo service mysql start 
SCRIPT

  config.vm.provision "shell", inline: $script, privileged: false, run: "always"
end
  1. A symfony2 project runs inside the box. Here is its require section of composer.json
    "require": {
        "php": ">=5.3.3",
        "symfony/symfony": "2.2.*",
        "doctrine/orm": "~2.2,>=2.2.3",
        "doctrine/doctrine-bundle": "1.2.*",
        "twig/extensions": "1.0.*",
        "symfony/assetic-bundle": "2.1.*",
        "symfony/swiftmailer-bundle": "2.2.*",
        "symfony/monolog-bundle": "2.2.*",
        "sensio/distribution-bundle": "2.2.*",
        "sensio/framework-extra-bundle": "2.2.*",
        "sensio/generator-bundle": "2.3.*",
        "jms/security-extra-bundle": "1.4.*",
        "jms/di-extra-bundle": "1.3.*",
        "kriswallsmith/assetic": "v1.1.0-alpha4",
        "gedmo/doctrine-extensions": "dev-master",
        "stof/doctrine-extensions-bundle": "dev-master",
        "doctrine/doctrine-fixtures-bundle": "dev-master",
        "mopa/bootstrap-bundle": "2.2.x-dev",
        "twbs/bootstrap": "2.3.1",
        "jlong/sass-twitter-bootstrap": "2.3.1",
        "liip/theme-bundle": "dev-master",
        "fkr/cssurlrewrite-bundle": "*",
        "knplabs/knp-paginator-bundle": "dev-master",
        "knplabs/knp-components": "dev-master#f096dd02136957ce1fba5819261a45b3ee9ed4a7",
        "craue/formflow-bundle": "dev-master",
        "sonata-project/admin-bundle": "dev-master",
        "sonata-project/cache-bundle": "dev-master",
        "sonata-project/doctrine-orm-admin-bundle": "dev-master",
        "avalanche123/imagine-bundle": "v2.1",
        "r1pp3rj4ck/TwigstringBundle": "dev-master",
        "raulfraile/ladybug-bundle": "1.0.1"
    },

Problem:

When opening even an empty page like login form, it takes too long. As seen in profiler, the majority of time is taken by twig render:

Twig taking 3.5 seconds to render

What I have tried:

  1. as you see in Vagrantfile, NFS is enabled. Not sure how to test it
  2. Read this and this . The test you see on the screenshot above was run after those changes are done

Solution

  • In order to make it work faster in vagrant in case your host OS is Win (Windows 7 x64 in my case), you need to:

    1. add this fix. I also added 'prod' environment to the list:
    public function getCacheDir()
    {
        if (in_array($this->environment, array('dev', 'test', 'prod'))) {
            return '/dev/shm/project/cache/' .  $this->environment;
        }
    
        return parent::getCacheDir();
    }
    
    public function getLogDir()
    {
        if (in_array($this->environment, array('dev', 'test', 'prod'))) {
            return '/dev/shm/project/logs';
        }
    
        return parent::getLogDir();
    }
    
    1. Fix I/O performance by utilizing NFS. The thing is that I was confused: setting nfs=true option in synced_folders does NOT mean you're connecting through NFS. My host OS is Win7 and I had to install NFS server in order to make it work. Note that it's not free. Here are two folders I had to share:

    enter image description here

    Also, mounting with synced_folder did not work for me, as NFS server was only listening on specific IP address, so I had to comment out this:

    config.vm.synced_folder "../../../project", "/var/www", type: "nfs",:nfs => true
    

    and put this instead:

    $script = <<SCRIPT
      sudo mount 192.168.178.40:/d/project /var/www/ && sudo mount 192.168.178.40:/d/project/_conf /etc/apache2/sites-enabled && sudo service apache2 restart
    SCRIPT
    
      config.vm.provision "shell", inline: $script, privileged: false, run: "always"
    

    ,where 192.168.178.40 is the IP where NFS ports are open. You can scan it from yout gurest OS with, e.g. nmap.

    1. And you'll also need to install vagrant plugin called vagrant-winnfsd. It can be done by:

    vagrant plugin install vagrant-winnfsd