Normally we deploy our projects using Capistrano and it has worked very well so far with WordPress and Drupal. However, there were a few nags with deploying Symfony projects. We could not get the correct file permissions set after deployment. This prevented the cache from being rebuilt and the logs being written to.

After several attempts to rectify this issue I decided to try a different path. There are deployment tools built in PHP to choose from which makes it a bit easier to write custom deploy scripts. At least you don’t have to make the mental leap between PHP and Ruby while developing.

I settled on Magallanes because it was recommended on Symfony’s deployment page and it seemed easy to set up and extend. And indeed it is.
Following the instructions I decided install both globally and locally in my Symfony project. The idea being that PHPStorm can autoload the Magallanes classes which will make using the API much easier.

After that I simply initiated the project and added an environment as per instructed. The environment configuration is a breeze. The only thing I did that was custom was adding Symfony specific tasks under the on-deploy tasks.

- fix-permissions
- symfony2/cache-warmup: {env: prod}

The first task is one that I added to my custom tasks, the second is a built in task from Magallanes. As for the custom task, you may recognize it from the examples on the Magallanes page. I simply modified it a little to fix the permissions on the cache and logs folders.

<?php
namespace Task;

use Mage\Task\AbstractTask;

class FixPermissions extends AbstractTask
{
   public function getName()
   {
      return 'Fixing file permissions';
   }

   public function run()
   {
      $command = 'chmod 755 . -R';
      $result = $this->runCommandRemote($command);

      if ( true == $result ) {
         $result = $this->fixCachePermissions();
      }

      if ( true == $result ) {
         $result = $this->fixLogsPermissions();
      }

      return $result;
   }


   public function fixCachePermissions() {
      $command = 'chmod 775 ./app/cache -R';
      $result = $this->runCommandRemote($command);

      return $result;
   }


   public function fixLogsPermissions() {
      $command = 'chmod 775 ./app/logs -R';
      $result = $this->runCommandRemote($command);

      return $result;
   }
}

The only real gotcha with creating your own tasks is that the PHP file must be named after your class and camel case is converted to lowercase with hyphens separating the words in your environments file.
So your FixPermissions class lives in FixPermissions.php and is called by fix-permissions in the environment file.

When you deploy your project to your environment you don’t have to prepare anything in the target folder. If you’ve used Capistrano you will recognize the way that the folders are set up by default with the running code in the current-folder and the linked releases in the releases-folder. This is customizable if you prefer something else.

I had the whole setup up and running in about an hour which was very gratifying after having spent lots of hours trying to get Capistrano to play ball. Now I am certain that you can get Capistrano to do this as well, but this was such an easy fix for our problem.