OxyScripts.com
Menu spacer Home Tutorials Articles Code Forums irc.freenode.net #oxyscripts
Main (PHP)
Home Forums PHP News PHP Tutorials Articles PHP Code Snippets Contact Us Sysadmin Resources Books Template Shop
3rd Party Streams
SlashDot PHPDeveloper.org PHP.Net
Resources
PHP Manual MySQL Manual Smarty Manual PEAR Manual PHP-GTK Manual Symfony Manual
Code Snippets
Authentication Database Graphics HTTP Miscellaneous Time/Date
Affiliates
Scripts TutorialMan TutorialGuide CodingForums.com PHP Scripts Cheap Web Hosting Affordable Web Hosting Dreamweaver Templates

Search This Site :     PHP Function Reference :
 

How to deploy a project to production

Overview

Symfony offers shorthand commands to synchronize two versions of a website. They are mostly used to deploy a website from a development server to a final host, connected to the Internet.

Synchronization

Good practices

There are a lot of ways to synchronize two environments for a website. The basic file transfers can be achieved by an FTP connection, but there are two major drawbacks to this solution. First, it is not secure, the data stream transmits in the clear over the Internet and can be intercepted. Second, sending the root project directory by FTP is fine for the first transfer, but when you have to upload an update of your application, where only a few files changed, this is not a good and fast way to do it. Either you transfer the whole project again, which can be long, or you browse to the directories where you know that some files changed, and transfer only the ones with different modification dates. That's a long job, and it is prone to error. In addition, the website can be unavailable or buggy during the time of the transfer.

The solution that is supported by symfony is rsync synchronization through a SSH layer.

Rsync is a command line utility that provides fast incremental file transfer, and it's open source. By 'incremental', it means that only the modified data will be transferred. If a file didn't change, it won't be sent to the host. If a file changed only partially, only the differential will be sent. The major advantages is that rsync synchronizations transfer only a little data and are very fast.

Symfony adds SSH on top of rsync to secure the data transfer. More and more commercial hosts support an SSH tunnel to secure file uploads on their servers, and that's a good practice that symfony encourages.

For notes on installing rsync and SSH on Linux, read the instructions in the related websites. For Windows users, an open-source alternative called cwRsync exists, or you can try to install the binaries by hand (instructions can be found here). Of course, to be able to setup an SSH tunnel between an integration server and a host server, the SSH service has to be installed and running on both computers.

The symfony sync command

Doing a rsync over SSH requires several commands, and synchronization can occur a lot of times in the life of an application. Fortunately, symfony automates this process with just one command:

$ symfony sync production

This command, called from the root directory of a symfony project, launches the synchronization of the project code with the production hosted server. The connection details of this server are to be written in the project properties.ini, found in myproject/config/:

name=myproject

[production]
  host=myapp.example.com
  port=22
  user=myuser
  dir=/home/myaccount/myproject/

The connection settings will be used by the SSH client call enclosed in the symfony sync command line.

Note: don't mix up the production environment (the host server, as defined in the properties.ini of the project) with the prod environment (the front controller and configuration used in production, as referred to in the configuration files of an application)

If you just call symfony sync like mentioned above, the rsync utility will run in dry mode by default (--dry-run), i. e. it will show you which files have to be synchronized but without actually synchronizing them. If you want the synchronization to be done, you have to mention it explicitly:

$ symfony sync production go

Ignore irrelevant files

If you synchronize your symfony project with a production host, there are a few files and directories that should not be transferred:

  • All the .svn directories and their content: They contain source version control information, only necessary for development and integration
  • myproject/web/fronted_dev.php: The web front controller for the development environment must not be available to the final users. The debugging and logging tools available when using the application through this front controller slow down the application, and give information about the core variables of your actions. It is something to keep off of the host server.
  • The cache/ and log/ directories of a project must not be erased in the host server each time you do a synchronization. These directories must be ignored as well. If you have a stats/ directory, it should probably be treated the same.
  • The files uploaded by users: one of the good practices of symfony projects is to store the uploaded files in the web/uploads/ directory. This allows us to exclude all these files by pointing to only one directory.

To exclude files from rsync synchronizations, open and edit the rsync_exclude.txt file under the myproject/config/ directory. Each line can contain either a file, a directory, or a pattern:

.svn
cache
log
stats
web/uploads
web/myapp_dev.php

Thanks to the symfony file structure, you don't have too many files or directories to exclude manually from the synchronization. If you want to learn more about the way the files are organized in a symfony project, refer to the file structure chapter.

Note: The cache/ and log/ directories must not be synchronized with the development server, but they must at least exist in the production server. Create them by hand if the myproject/ project tree structure doesn't contain them.

Production server configuration

For your project to work in the production server, the symfony framework has to be installed in the host.

Install symfony in a production server

There are several ways to install symfony on a server, but they are not all adapted to a production environment. For instance, doing a PEAR install requires administrator rights on directories that might not be open to you if you share a web server.

Based on the principle that you will probably host several projects using symfony on the production web server, the recommended symfony installation is to uncompress the archive of the framework in a specific directory. Only the lib/ and data/ directories are necessary in a production server, so you can get rid of the other files (bin/, doc/, test/ and the files from the root directory).

You should end up with a file structure looking like:

/home/myaccount/    
  symfony/
    lib/
    data/
  myproject/
    apps/
    batch/
    cache/
    config/
    data/
    doc/
    lib/
    log/
    test/
    web/

For the myproject project to use the symfony classes, you have to set up two symbolic links between the application lib/symfony and data/symfony, and the related directories in the symfony installation:

$ cd /home/myaccount/myproject
$ ln -sf /home/myaccount/symfony/lib lib/symfony
$ ln -sf /home/myaccount/symfony/data data/symfony

Alternatively, if you don't have command line access, the files of the framework can be copied directly into the project lib/ and data/ directories:

copy /home/myaccount/symfony/lib/*   into /home/myaccount/myproject/lib/symfony
copy /home/myaccount/symfony/data/*  into /home/myaccount/myproject/data/symfony

Beware that in this case, each time you update the framework, you have to do it in all your projects.

For more information, all the possible ways to install symfony are described in the installation chapter.

Access to the symfony commands in production

While developing, you probably often use the following command:

$ symfony clear-cache

It is necessary, at least, each time you change the configuration or the object model of the project. When you upload a new version of your project in production, the cache also needs to be cleared if you want the application to work. You can easily do it by deleting the full content of the myproject/cache/ directory (by ftp or with a ssh console). Alternatively, you can have the power of the symfony command line in the production host at the price of a slightly longer installation.

To use the command line, you need to install the pake utility. Pake is a PHP tool similar to the make command. It automates some administration tasks according to a specific configuration file called pakefile.php. The symfony command line uses the pake utility, and each time you type symfony, you actually call pake with a special pakefile.php located in the symfony/bin/ directory (find more about pake in symfony in the project creation chapter). If you install symfony via PEAR, pake is installed as a requirement, so you usually don't see it at all and don't need to bother about what comes next. But if you do a manual installation, you have to uncompress the pake directory (get it from your symfony pear installation or download it from the pake website) into your directory in the production server. Just like for the symfony libs, you also have to add a symlink in order to enable symfony to use pake:

$ ln -sf /home/myaccount/pake/lib lib/pake

You should end up with something like this:

/home/myaccount/
  pake/
    lib/      
  symfony/
    lib/
    data/
  myproject/
    apps/
    batch/
    cache/
    config/
    data/
      symfony/ -> /home/myaccount/symfony/data
    doc/
    lib/
      symfony/ -> /home/myaccount/symfony/lib
      pake     -> /home/myaccount/pake/data
    log/
    test/
    web/

To call the symfony command to do a clear-cache, you need to do:

$ cd /home/myaccount/myproject/
$ php lib/pake/bin/pake.php -f lib/symfony/data/symfony/bin/pakefile.php clear-cache

Alternatively, you can create a file called symfony in the home/myaccount/myproject/ with:

#!/bin/sh

php lib/pake/bin/pake.php -f lib/symfony/data/symfony/bin/pakefile.php $@

Then, all you need to do in order to clear the cache is that good old

$ symfony clear-cache

Web command

If you want to have the power of the pake utility but without command line access, you can also create a web access for the clear-cache command.

For instance, you could save the following webpake.php in your /home/myaccount/myproject/web/ directory:

<?php
 
// as we are in the web/ dir, we need to go up one level to get to the project root
chdir(dirname(__FILE__).DIRECTORY_SEPARATOR.'..');
 
include_once('/lib/symfony/pake/bin/pake.php');
 
$pake = pakeApp::get_instance();
try
{
  $ret = $pake->run('/data/symfony/bin/pakefile.php', 'clear-cache');
}
catch (pakeException $e)
{
  print "<strong>ERROR</strong>: ".$e->getMessage();
}
 
?>

Then, clearing the cache could be done by navigating to:

http://myapp.example.com/webpake.php

Note: Beware that by letting web access to administration tools, you can compromise the safety of your website.

Upgrading your application

There will be times in the life of your project when you need to switch between two versions of an application. It can be in order to correct bugs, or to upload new features. You can also be faced with the problem of switching between two versions of the database. If you follow a few good practices, these actions will prove easy and harmless.

Show unavailability notice

Between the moment when you start the data transfer and the moment you clear the cache (if you modify the configuration or the data model), there are sometimes more than a few seconds of delay. You must plan to display an unavailability notice for users trying to browse the site at that very moment.

In the application settings.yml, define the unavailable_module and unavailable_action settings:

all:
  .settings:
    unavailable_module:     content
    unavailable_action:     unavailable

Create an empty content/unavailable action and a unavailableSuccess.php template:

// myproject/frontend/modules/content/actions/actions.class.php
public function executeUnavailable()
{
  $this->setTitle('website maintenance');
}
 
// myproject/frontend/modules/content/templates/unavailableSuccess.php
<h1>Site maintenance</h1>
 
<p>The website is currently being updated.</p>
 
<p>Please try again in a few minutes.</p>

Now each time that you want to make your application unavailable, just change the available setting:

all:

  .settings:

    available:              off

Don't forget that for a configuration change to be taken into account in production, you need to clear the cache.

Note: The fact that the whole application can be turned off with only a single parameter is possible because symfony applications use a single entry point, the front web controller. You will find more information about it in the controller chapter.

Use two versions of your application

A good way to avoid unavailability is to have the project root folder configured as a symlink. For instance, imagine that you are currently using the version 123 of your application, and that you want to switch to the version 134. If your web server root is set to /home/myaccount/myproject/web/ and that the production folder looks like that:

/home/myaccount/
  pake/
    lib/      
  symfony/
    lib/
    data/
  myproject/     -> /home/production/myproject.123/
  myproject.123/
  myproject.134/

Then you can instantly switch between the two versions by changing the symlink:

$ ln -sf /home/myaccount/myproject/ /home/myaccount/myproject.134/

The users will see no interruption, and yet all the files used after the change of the symlink will be the ones of the new release. If, in addition, you emptied the cache/ folder of your release 134, you don't even need to launch a clear-cache after switching applications.

Switch databases

You can extrapolate that technique to switching databases. Remember that the address of the database used by your application is defined in the databases.yml configuration file. If you create a copy of the database with a new name, say myproject.134, you just need to write in the myproject.134/frontend/config/databases.yml:

all:
  propel:
    class:        sfPropelDatabase
    param:
      datasource: symfony
      phptype:    mysql
      hostspec:   oxyscrip.ipowermysql.com
      database:   myproject.134
      username:   myuser
      password:   mypassword
      compat_assoc_lower: true
      compat_rtrim_string: true

As the databases.yml will be switched as the same time as the application itself, your application will instantly start querying the new database.

This technique is especially useful if your application has lots of traffic and if you can't afford any service interruption.

TODO

  • Upgrading the data model
  • Synchronization and source versioning
  • reverting to a previous version
 
   Print this page

Top Sponsor
Symantec\'s Norton SystemWorks 2006
Sponsors
CA
Sponsors
AdWords Dominator 125*125
Advertisting


Affiliates
VertexTemplates PHPFreaks CodeWalkers StarGeek DevScripts CGI & PHP Scripts PHP CMS Free Templates

Shopping Rebates   Sell It 4 You   Flash Page Counters   Get Insured
GPS Tracking Service   Charity Donate Info   Web Site Hosting   VOIP Service

Privacy Policy | Links | Site Map | Advertising

All content on OxyScripts.com is (©)2002-2007

 
Powered by Adrastea - Version 1.0.0. Copyright © Rune Solutions, 2004-2005