Symfony offers shorthand commands to synchronize two versions of a website. These commands are mostly used to deploy a website from a development server to a final host, connected to the Internet.
16.4.1. Freezing a Project for FTP Transfer
The most common way to deploy a project to production is to transfer all its files by FTP (or SFTP). However, symfony projects use the symfony libraries, and unless you develop in a sandbox (which is not recommended), or if the symfony
data/ directories are linked by
svn:externals, these libraries are not in the project directory. Whether you use a PEAR installation or symbolic links, reproducing the same file structure in production can be time-consuming and tricky.
That's why symfony provides a utility to "freeze" a project--to copy all the necessary symfony libraries into the project
web/ directories. The project then becomes a kind of sandbox, an independent, stand-alone application.
> symfony freeze
Once a project is frozen, you can transfer the project directory into production, and it will work without any need for PEAR, symbolic links, or whatever else.
Tip Various frozen projects can work on the same server with different versions of symfony without any problems.
To revert a project to its initial state, use the
unfreeze task. It erases the
> symfony unfreeze
Note that if you had symbolic links to a symfony installation prior to the freeze, symfony will remember them and re-create the symbolic links in the original location.
16.4.2. Using rsync for Incremental File Transfer
Sending the root project directory by FTP is fine for the first transfer, but when you need to upload an update of your application, where only a few files have changed, FTP is not ideal. You need to either transfer the whole project again, which is a waste of time and bandwidth, or browse to the directories where you know that some files changed, and transfer only the ones with different modification dates. That's a time-consuming 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 an SSH layer. Rsync (http://samba.anu.edu.au/rsync/) is a command-line utility that provides fast incremental file transfer, and it's open source. With incremental transfer, only the modified data will be sent. If a file didn't change, it won't be sent to the host. If a file changed only partially, just the differential will be sent. The major advantage is that rsync synchronizations transfer only a small amount of 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 to avoid security breaches.
The SSH client called by symfony uses connection settings from the
config/properties.ini file. Listing 16-14 gives an example of connection settings for a production server. Write the settings of your own production server in this file before any synchronization. You can also define a single parameters setting to provide your own rsync command line parameters.
Listing 16-14 - Sample Connection Settings for a Server Synchronization, in
[symfony] name=myproject [production] host=myapp.example.com port=22 user=myuser dir=/home/myaccount/myproject/
Note Don't confuse the production server (the host server, as defined in the
properties.ini file of the project) with the production environment (the front controller and configuration used in production, as referred to in the configuration files of an application).
Doing an 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 launches the rsync command in dry mode; that is, it shows which files must be synchronized but doesn't actually synchronize them. If you want the synchronization to be done, you need to request it explicitly by adding
> symfony sync production go
Don't forget to clear the cache in the production server after synchronization.
Tip Sometimes bugs appear in production that didn't exist in development. In 90% of the cases, this is due to differences in versions (of PHP, web server, or database) or in configurations. To avoid unpleasant surprises, you should define the target PHP configuration in the
php.yml file of your application, so that it checks that the development environment applies the same settings. Refer to Chapter 19 for more information about this configuration file.
16.4.3. Ignoring Irrelevant Files
If you synchronize your symfony project with a production host, a few files and directories should not be transferred:
- All the version control directories (
CVS/, and so on) and their content are necessary only for development and integration.
- The 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 away from the public.
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 way.
- The files uploaded by users should not be transferred. One of the good practices of symfony projects is to store the uploaded files in the
web/uploads/directory. This allows you to exclude all these files from the synchronization 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 a file, a directory, or a pattern. The symfony file structure is organized logically, and designed to minimize the number of files or directories to exclude manually from the synchronization. See Listing 16-15 for an example.
Listing 16-15 - Sample rsync Exclusion Settings, in
.svn /cache/* /log/* /stats/* /web/uploads/* /web/myapp_dev.php
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.
16.4.4. Managing a Production Application
The command that is used most often in production servers is
clear-cache. You must run it every time you upgrade symfony or your project (for instance, after calling the
sync task), and every time you change the configuration in production.
> symfony clear-cache
Tip If the command-line interface is not available in your production server, you can still clear the cache manually by erasing the contents of the
You can temporarily disable your application--for instance, when you need to upgrade a library or a large amount of data.
> symfony disable APPLICATION_NAME ENVIRONMENT_NAME
By default, a disabled application displays the
default/unavailable action (stored in the framework), but you can customize the module and action to be used in this case in the
settings.yml file. Listing 16-16 shows an example.
Listing 16-16 - Setting the Action to Execute for an Unavailable Application, in
all: .settings: unavailable_module: mymodule unavailable_action: maintenance
enable task reenables the application and clears the cache.
> symfony enable APPLICATION_NAME ENVIRONMENT_NAME