Distributing your project with symfony embedded

With symfony 1.0, one of the nice features was the freeze option, which allowed you to package the symfony libraries inside your project quite easily. This was very useful, for instance when deploying your project on a server where you couldn't install symfony. With symfony 1.1, it is apparently not advised anymore to use the freeze option (even though it is still available). So how should this be done then? Let's have a look...

I was a bit surprised earlier that freezing your project was not really advised anymore, it was the way I was used to working with my symfony 1.0 projects. However, with symfony 1.1 and some pointers I have found the new way of doing things to be very pleasant. So let me share it with you.

There are several reasons for embedding symfony inside your project. On your development environment, a reason can be to easily enable symfony 1.0 and 1.1 projects to be developed side by side. On your production server, it can be because you have no control over centrally installed libraries. But moreover because the right setup can ensure you always have the latest version. Let me elaborate on how I do this.

First of all, my central installation of symfony. It is a complete checkout of the symfony svn repository, which means I have the symfony 1.0, 1.1 and even 1.2 branch locally checked out for usage. However, I hardly use these. I only use them to create a new project. After that, it's all up to Subversion.

Creating a new project

When I create a new project, I use the centrally installed symfony checkout:

/path/to/symfony/repo/branches/1.1/bin/symfony generate:project newproject

This will create my new project in the current directory. This is just the project skeleton, and it is still using the symfony that can be found in /path/to/symfony/repo/branches/1.1

But first... Subversion

My initial new project needs to be put into Subversion first though. I import my new project and create a fresh checkout to work with. This means I can start using some nice advanced features of Subversion for embedding symfony into my project.

The vendor directory

The location for our symfony installation will eventually be lib/vendor/symfony in our project. For this to happen, the vendor/ directory needs to be created and added to Subversion. So I do:

mkdir lib/vendor
svn add lib/vendor
svn commit lib/vendor -m "added vendor directory"

Now, my vendor directory is ready for adding symfony.

svn:externals

It is of course possible now to put a copy of symfony in the lib/vendor/symfony directory. And this works fine if you want it. The downside of this approach is that any symfony upgrade needs to be done manually, which can be a pain. 

There are also strategies which keep a copy of the libraries inside the repository by using "vendor branches". This is an option as well, yet it still keeps the library code locally where there should be no need for such a thing.

Instead, in my setup, I use an svn:externals property to link the lib/vendor/symfony directory directly to the symfony repository. The advantage with this is that every time I do an svn up, I also get updates from the symfony repository, which may contain fixes for bugs that I could encounter. So, let's set up this external link in our project repository. 

svn propedit svn:externals lib/vendor

This opens a new editor window of my favorite editor for such tasks (in my case vim, could be different for you). In this editor, I add a line:

symfony http://svn.symfony-project.com/branches/1.1

What this line says is that a directory named symfony [inside the lib/vendor directory, as specified in the svn propedit command above] needs to contain the contents of the 1.1 branch out of the symfony svn repository. In my case, I am using the branch, but if you want more stability, you could link to a release tag, for instance the current 1.1.4 release tag.This will give you the stability of a release, but not the fixes of recent commits. However, when a new release comes out, you can always simply use the propedit command again to switch to the next tag.

Once I've created the svn:externals link to the external repository, I can simply do:

svn up lib/vendor

To get the latest version of symfony in my project. Do not forget to commit lib/vendor to get your svn:externals change propagated in your subversion repository.

Switch to your new checkout

This is all nice, but symfony is at this point still using the symfony installation I used to create the project. I need to point my project to it's internal symfony checkout. Luckily, with symfony 1.1, this is very easy as it requires only a single change. This change needs to be made in our project configuration, which can be found in config/ProjectConfiguration.class.php. In this file, there is a require line that currently contains the hardcoded path to the location of the symfony installation that you used to create this project. We will need to change this to a relative location inside our project:

require_once dirname(__FILE__) . '/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';

I am using a relative path to the ProjectConfiguration.class.php file here. I could hardcode this path to our project installation of symfony, however, there is a good chance that the server path to your project will not be the same on your test, staging or production machines. Therefore, making the path relative will ensure that your project runs on any of these machines without altering the configuration file.

The default styles and javascripts

Now there is one more thing left. Your default assets. So far I have not created my virtualhost configuration yet, but I need to ensure that this works. I could create a symlink in the web/ directory to lib/vendor/symfony/data/web/sf but those don't work well with Subversion (or other platforms). Best is to use the Alias option in your virtualhost configuration. Instead of having this point to my centralized symfony installation (as I used to do), I can now simply point it to the symfony in my project:

Alias /sf /var/www/mynewproject/lib/vendor/symfony/data/web/sf

And we're done. The only thing you need to do when you deploy this to another server (and this should only happen once per server) is that the last step, the virtualhost configuration, is done for that specific server setup. Once that is done, you're set.

As with many of symfony's features, this process is aimed at not duplicating the tasks you need to execute in your project. You only set this up once (in your development environment), and once that is done, you can deploy to as many systems as you want without having to do the same steps all over again. 


Add comment

Comments

gravatar chris: we do nearly like you except that we also create an svn:externals for the sf dir in our web directory (so that we do not need to modify the vhost config on our servers)
October 10, 2008
gravatar left: Hi Chris,

That is actually a good idea, I never thought of that. That solves the manual server configuration issue completely. Excellent idea, thanks.
October 10, 2008
gravatar Vid Luther: Just a quick clarification question.

Now, that you're using SVN externals and not using symfony freeze etc. Do you tag your development branch when it's "ready" for deployment, and then do an svn export of the tag in your production environment? Or do you still use symfony's tools to push to production?

Otherwise very informative article, I'll be deploying a symfony 1.1 project in the next week, and I'll use the methods here to setup the dev/stage areas so I can test things, and then deploy onto a server where I probably won't get root :)
October 10, 2008
gravatar left: Hi Vid,

Deployment is a different topic I guess (which I wrote about before), but let me clarify my approach on that:

Once I have a new version ready for deployment, I tag it in subversion. I do an export of the tagged version in a temporary directory, from which I then use ./symfony project:deploy to deploy to the server. So yes, I still use symfony's built-in deployment features, and actually in 1.2 or 1.3 we will get a more improved version of the deployment system, so there is absolutely no reason to move away from that :)
October 10, 2008
gravatar tom: you write that using "freeze" with symfony 1.1 ist not "advised" anymore.. Where did you get this advise from? In the current 1.1 documentation the freeze command is still described..

i used "freeze" a lot to deploy my projects on shard hosting servers.. there i cant use the method u describe.... thats why i would like to know, where you read/heard, that freeze should not be used with 1.1

thx..
October 10, 2008
gravatar Vid Luther: Thanks Stefan,
I'm curious what you feel are the advantages of the symfony deploy method, vs an svn export of the tag on the production server? Is it basically not having to worry about the svn server not having svn on it?

As I await your response, I'm googling symfony project:deploy
October 10, 2008
gravatar left: Tom: I was told that by Fabien, I think it was during our DPC tutorial.

Vid: I prefer to push new stuff instead of pulling it. I don't want my .svn directories to be "polluting" my production environment (so I want an export). But with an export, I need to move away my old version and put the new version in place. This may be a problem with uploaded files for instance. Too much to think of.

When using the project:deploy, only the changed files are pushed to the new server, and uploaded files stay where they are. There are no unnecessary files such as .svn stuff in there. It's less actions to accomplish the same thing. This also means less points where something might go wrong :)

You might find http://www.leftontheweb.com/message/Deployment_as_it_should_be interesting.
October 10, 2008
gravatar left: Oh and Tom, you can use the above described method on any shared hosting account as well. Because the svn export (which pulls the symfony into your lib/vendor directory) is in my case done on my local machine, before I project:deploy to the server. In the end, you'll end up with a similar setup as freeze.
October 10, 2008
gravatar Phil Moorhouse: Have you managed to do this with symfony 1.0.x ?

I attempted to do the same with
http://svn.symfony-project.com/tags/RELEASE_1_0_18/

but once I've modified the config.php to point at the correct directories:
$sf_symfony_lib_dir = dirname(__FILE__).'/../lib/vendor/symfony_1_0/lib';
$sf_symfony_data_dir = dirname(__FILE__).'/../lib/vendor/symfony_1_0/data';

I get a fatal error relating to /test/bootstrap/unit.php attempting to redeclare sfException - I guess the autoloader is including all the test files because it's under /lib.

Is there a way to include the symfony libs without the test dirs?

October 10, 2008
gravatar left: Phil,

I am not sure how easy it is. I've always used freeze with 1.0, and it was not until I started working with 1.1 that I found out about this new method. It is highly likely that for 1.0 there are several dependencies internally that makes this approach for 1.0 projects a problem, but I haven't tried it so I can't really tell you anything about it. I only know that in 1.1, there is only the dependency on the ProjectConfiguration, which makes it easier to use this approach.
October 10, 2008
gravatar Sherif: Great post, however I would not recommend this strategy if you want to host multiple Symfony sites on the same server - you will end up with quite a very large code-base (one Symfony instance per app). This is great but, for distributing your symfony apps.

If you are looking at hosting multiple apps on the same server, you are better of sharing the same Symfony libs for each version of Symfony - Here is how to do it: http://symfonynerds.com/blog/?p=123

Agree with your comment about freezing - I like that idea.. not sure really why it was taken out but..
October 10, 2008
gravatar ken: I also use subversion when managing/deploying my application.

cd project
svn propedit svn:ignore .*
cd log
svn propedit svn:ignore *
cd ../cache
svn propedit svn:ignore *
cd ../plugins
svn propedit svn:ignore .*

plugins as external
web/sf as external

i also make sure that i have a tagged copy of symfony in our repositiory plus the plugins

make sure also to ignore the om and map folders of plugins so that when you do commits, the repository will not be updated, just override them in lib dir

create also a template of config/config.php
cp config.php config.php.sample
svn propedit svn:ignore config.php

this way no freeze is needed. all you need to do is copy config.php.sample and modify the paths
October 21, 2008
gravatar Mark Quezada: I use pretty much the same approach, but I simply make a symlink from "/sf" to "../../lib/vendor/symfony/data/web/sf"

If you're on a unix box it makes it a whole lot easier and you don't have to have to svn:external links pointing to essentially the same thing.

Phil: I wrote an article a while back about using this approach on symfony 1.0: http://blog.mirthlab.com/2007/12/15/setting-up-a-symfony-project-on-media-temples-grid-service-part-1/

Look under "setting up symfony."

Also, I frequently reference this article which has several good tips on this: http://spindrop.us/2007/04/17/tips-for-symfony-and-subversion/

Hope that helps.
October 22, 2008
gravatar Open: Good idea, thank you.

Open
October 26, 2008
gravatar Colnector: svn:externals is the most flexible way to work since you can be just as updated as you like. I recommend to always compare the Symfony lib changes before updating your site’s webserver.
December 25, 2008
gravatar Dynamics CRM: Upon completing this I end up having to do more than the virtualhost configuration when changing servers. Originally, I thought I was erroneously creating the relative path, but that doesn't seem to be the issue. Maybe if I try the advice in the comments regarding not needing to modfy the vhost config I will somehow bypass whatever is giving me issues. Nonetheless, I think I might be bothered even more if the problem is resolved without me understanding why!
April 24, 2011
gravatar dissertation help: Creatively great stuff!

May 5, 2011
gravatar zoloft lawsuit: This is so good how this works. There is so much that you can use this for. I see so much from this.
October 28, 2011
gravatar Bank online: I think being able to have this option is so good. There is so much that you can do with this. This is what makes this so good.
October 29, 2011
gravatar essay writing help: Great stuff, nice to find something like this! Thanks for writing!
December 5, 2011
gravatar barmsaktrc: Upon completing this I end up having to do more than the virtualhost configuration when changing servers. Originally, I thought I was erroneously creating the relative path, but that doesn't seem to be the issue. Maybe if I try the advice in the comments regarding not needing to modfy the vhost config I will somehow bypass whatever is giving me issues. Nonetheless, I think I might be bothered even more if the problem is resolved without me understanding why!

December 23, 2011
gravatar plumbers north london: Wow symphony is really great problem for me.I got a lot of information from this post.
January 1, 2012
gravatar coach outlet online: If you buy Coach items at the
coach outlet online

store, the goods will be sent out within 24 hours after confirming your payment and arrive to your door within 7 work days.No one can deny the shopping at the
coach factory outlet

is satisfactory. For the low prices and good quality.
January 29, 2012
gravatar coach outlet: coach outlet

handbags You can not just save your cash but also your time inside a convenient way to obtain the exact same bags product and do not be concerned the shippment of one's products.The
coach outlet store online

are utilized for formal event in company area that will display your excellent taste.Not only does a briefcase make is easier to carry things.
January 29, 2012
gravatar discount uggs boots: Your first-class knowledge about this good post can become a proper basis for such people. nice one! :?:
February 1, 2012
gravatar michael michael kors: Thanks for the great information. Sometimes its difficult to figure this stuff out without any help. Its good to know that help can be found here, thanks....

February 1, 2012

Php5_zce_logo

Upcoming events

I will be speaking 06-02-2012: D-Day
I will be speaking 17-02-2012: Techademy Trainingday February
I will be speaking 23-02-2012: Zend Webinar: Git for Subversion Users

Tags

1337 2008 2010 2011 4developers access modifiers accessibility AdaLovelaceDay09 advent agavi agile alfred amsterdam apache api apple article articles atk atkMetaNode audioscrobbler automation azure backwards compatibility barcelona barcodes bash bbc bbq beatstad belgium best practices bittorrent blogging blogs boards of canada book books bughuntday bundle caching cake cal evans calendar career cat cerf certificate cfp clear cms cologne common sense communities community components conference conferences contest continuous integration contribute contribution crisis css custom d-day datetime DbFinderPlugin decorator decorators deployment devdays development directoryindex docblox doctrine documentation download dpc dpc09 dpc10 dpc11 DPC2008 dreamhost drupal dv7 eclipse ed editors efficiency enterprise errors event events expertise ezcomponents facebook finland flickr fork framework frameworks freelance freeze frontend fun game games geoip germany getting real git github gnome-do google google calendar googletalk graceful degradation hack hackers hidden gem hiphop howto hp HR html http i386 ibuildings icann ide ideasofmarch idm imovie indy ingewikkeld integration international php conference internet interview ipad IPC ipc ipc08 ipc10 ipc11se iterm2 javascript jenkins jenkins-php job job openings jobeet john peel joomla joomladays kiva kubuntu launcher launchy left on the web libraries library lighttpd lime linktuesday linux live london loudblog m2ts mac magazines malware mambo marjolein mediterra meeting meme meta methodology micro-financing microframework microsoft migration movie music mysql namespace namespaces netbeans netherlands newsfire nllgg nos odmarco open source opinion ORM osx paradiso paris partnership pavilion pear pecl performance personal pfc10 pfc11 pfcongres pfcongrez pfz photo php php5.3 phpabstract phpazure phpBB phpbb phpbelgium phpbenelux phpbnl10 phpday phpdoc phpdocumentor phpgg phpitalia phpnw phpnw08 phpnw11 phpstorm phptek phptek09 phpuk2009 phpUnderControl phpunit php|architect php|tek podcast politics portability postcrossing presentation presentations private projects protected prototype PSR-0 public python qa qr codes re2c recruiting refactoring review rewrite ruby on rails san francisco schedule scifi script security sensio seven things sfdaycgn sflive2011 shell scripting silex simplexml slides smfony software sogeti solar sound speakers spl ssh standard standards star trek static steer strings stylesheets subversion symfony symfony live Symfony2 symfonycamp symfonyday symfonylive symfonyUnderControlPlugin talk talks techademy technology techportal tek09 telecommuting terratec terrorism testfest testing textmate textpattern the right tool timeout tips tld todo tomas tools training twig uncon unet usability usergroup validation vhost video vim vinyl virus warp webinar weblogging webservices wiki windows winphp women wordpress work workshop world world of warcraft wpi writing wunderlist xml xpath xsd yara year youtube zc11 ZCE zemanta zend zend framework zend server zend studio zendcon Zend_Form zite
© 2004 - 2012 Stefan Koopmanschap + Powered by Symfony, photos powered by Flickr, links powered by Delicious, Shanghai smilies by Iconbuffet. Feeds: rss / atom. Left on the Web v4.4.0.1