2
votes

I'm just getting started with Symfony.

I'm using Git/github as a way of managing my project. I've set up two ignores for log and cache which is fine.

I now need to set up a production site. At the moment on this small project I've development and production on the same server but with different file locations and databases.

e.g.

www.example.com/mysymfonyproject_dev/  < development area
&
www.example.com/mysymfonyproject/      < Live / Production site

On server its /homes/sites/example.com/www/mysymfonyproject_dev & /home/sites/example.com/www/mysymfonyproject

So now I have cloned my project to the new production folder.
It of course ignores the log and cache folders but now I need to change the database.yml file for example and possible more to get the production area to work.

What is the best method of dealing with this?
Is there some other file I should add to .gitignore that can state what version this site is e.g. development or production.

OR is there a whole other way I can do this with out using git?

Which is best practice?

As you can imagine I don't want to have to update the database.yml file everytime I do a git push to my production site.

UPDATE:

I've got a development environment. What I'm looking for is a step by step guide to deploy to production. I could use git to do it but for example how do I go about setting up the environments in such a way that all setting will be right when i deploy. I do see that database.yml can have different settings for staging and production but where then do I tell symfony what site is what? as in how does symfony know that www.example.com/kickboxing is production and www.example.com/kickboxing_dev is staging?

UPDATE 2:

In the end for my specific requirements this seemed to work well.

1 <?php                                                                                                                          
2 
3 
4 require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
5 
6 $theurl = explode('/', $_SERVER['PHP_SELF']);
7 $mydir = $theurl[1];
8 
9 
10 if ($mydir == "mysymfonyproject")  //live
11 {
12     $configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);
13     sfContext::createInstance($configuration)->dispatch();
14 }
15 else // dev 
16 {
17     $configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true);
18     sfContext::createInstance($configuration)->dispatch();
19 }

I think using $_SERVER['SERVER_NAME'] would be better on local machines where you might config your hosts file e.g. mysymfonyproject.local just add to the index file and git repository is ffine then and all files are portable.

2
Symfony is environment aware, why are you not setting up environments in the symfony config files?Gerry
Absolutely I can, that is why I'm asking the question of exactly how I can do that and what is best practice given my setup.Derek Organ
Have you looked at the symfony "Getting started" guide and "A gentle introduction to symfony"? I'll be glad to help if you run into any specific problem, but what you are asking now is explained clear enough in the official docs. symfony-project.org/doc/1_4Gerry
Sorry maybe I'm missing something and admittedly I haven't read it all cover to cover but where in those two short guides does it explain about setting up environments?Derek Organ

2 Answers

6
votes

Since you updated your question, I can give you some relevant info.

As you now know, you have a cascading configuration system in symfony which allows different parameters for for example your database connection (among many other things) for your dev and prod environment.

As to deployment, symfony comes with a task that utilizes rsync to deploy. In general you do not need to tweak it much, it will by default not deploy any "dev" front controller, so it suits most basic needs. Note that even if the deployment script should exclude the dev front controllers from deploying at all, e ven if you would deploy them, they by default have a small security check which only allows access from localhost. If you need to exclude other files from deployment, you can edit config/rsync_exclude.txt

Detailed info in deploying here: http://www.symfony-project.org/gentle-introduction/1_4/en/16-Application-Management-Tools#chapter_16_deploying_applications

A big note though, is that this deployment script does NOT handle database deployment. You should do that manually. If you need to deploy database changes to an existing database, you could also do that manual, or look into Doctrine Migrations (assuming you use Doctrine).

Update: you can have a single frontend controller (index.php) for different apps and/or environments. You can either check the hostname or other things, but the cleanest solution I found and employ is setting Apache environment variables. In my Vhost config I'll do:

<VirtualHost *:80>
  Servername www.myproject.dev
  ...
  SetEnv SYMFONY_APP frontend
  SetEnv SYMFONY_ENV dev
  SetEnv SYMFONY_DEBUG 1
</VirtualHost>

Note that ofcourse I'll have a separate Vhost for every single app/env combination. You shouldn't be deploying vhost configs, so normally you'll only need to set this up once on each host. My modified index.php looks like this:

<?php

require_once dirname(__FILE__) . '/../config/ProjectConfiguration.class.php';

$app = isset($_SERVER['SYMFONY_APP']) ? $_SERVER['SYMFONY_APP'] : 'frontend';
$env = isset($_SERVER['SYMFONY_ENV']) ? $_SERVER['SYMFONY_ENV'] : 'prod';
$debug = isset($_SERVER['SYMFONY_DEBUG']) ? $_SERVER['SYMFONY_DEBUG'] : false;

$configuration = ProjectConfiguration::getApplicationConfiguration($app, $env, $debug);
sfContext::createInstance($configuration)->dispatch();

With this setup, I can just remove frontend_dev.php and any other frontend controllers apart from index.php from my repository.

0
votes

On a production server, the best practice is:

  • not to have any tools other than the ones absolutely needed for running the app in prod
  • prepare the deployed product in a pre-production environment, with access rights more opened than the prod environment.

But in your case, where there very well might be no pre-production environment, and where access rights are less an issue, Git might make sense.

In this case, I recommend dealing with configuration files by keeping the actual values outside of a VCS repository.

content filter

You can then take advantage of a content filter in order to, on checkout build the actual database.yml values.
A 'smudge' script (declared in a .gitattributes file part of your repo) can detect in which environment it is executed, and select the appropriate source in order to get the right values for building the file.
See "Git Config excludesfile for just a branch" for more details.