Deploying your Symfony 2.0 web app to the production server

I am developing a Symfony 2.0 web app. I wanted to get my app running on the production server as soon as possible so that I know that it will work there. I couldn’t find an article on the web that presents a straight forward howto for deploying the production environment of a Symfony 2.0 web app to a remote production server. After a bit of hacking, I figured out how to do it. This article details the quick and dirty method I used to get a Symfony 2.0 web app onto a production server.

It should be mentioned that there are tools which try to automate the deployment process such as capifony, though I personally couldn’t get capifony to work for me. Besides, I want to understand the process by which a Symfony 2.0 app can be manually migrated from the development environment on my machine to the production environment on a remote server before I start relying on tools to automate the process for me.

Development Environment

System: Mac OS X 10.6
HTTP Server: Apache 2.2.17 running mod_php
PHP: 5.3.4
Symfony2 Project dir: /Library/WebServer/Documents/symfony2

This is my local machine where I develop my web app.

Remote Production Server

System: Linux 2.6.18-374.3.1.el5.lve0.8.44 (results from uname -a on my account)
HTTP Server: Apache 2.2.21
PHP: 5.3.10 (running as a cgi process)
Symfony2 Project dir: /home/james/symfony2

This is a shared hosting account at Arvixe web hosting.

I can access my shared hosting account via ssh and run commands from a bash shell. Before I began, I created a ~/symfony2 dir on the remote server where my Symfony2 webapp will reside. I set the root dir of my domain name to point to ~/symfony2/web. Getting httpd to do this is beyond the scope of this article.

In this article, all relative paths are relative to the main symfony2 project dir. For example, web/ refers to /Library/WebServer/Documents/symfony2/web on my local machine and to ~/symfony2/web on my remote server.

Deploying the project

Check the remote environment

Note: While the following information specifically mentions my shared hosting provider, it should be relevant everywhere. If you are the admin of your own server, you are of course responsible for installing and configuring php 5.3 yourself.

You may find that your remote host does not yet have php 5.3.2 installed. This is a requirement for a Symfony2 project and you should have your site admin install it for you, if it isn’t hiding somewhere on your remote account already. The default command line (cli) php on Arvixe is PHP 5.2.17.

$ php --version
PHP 5.2.17 (cli) (built: Dec 22 2011 01:10:30)

You may have to do some digging for yourself in order to find where php53 lives on your remote host. Here is a hint on how to find it:

$ find / -name "php53" -print

I setup an alias in my .profile file that points to the php 5.3 bin:

alias php="/usr/local/php53/bin/php"

Now when I type ‘php’ in my shell I see this:

$ php --version
PHP 5.3.10 (cli) (built: Feb  5 2012 13:35:22) 

After this, I uploaded the script in app/check.php and ran it

$ php check.php

to make sure that Symfony2 will actually run. Everything was OK.

Arvixe provides php 5.3 as an option for web applications, which must be run by modifying my .htaccess file in my web/ dir. See this article for more information. Your server will probably have a similar setup and a line to add to your .htaccess file. You can always verify which php version your web server uses by running the simple script on your remote server in your browser:

<?php phpinfo(); ?>

Transfer the project dir via rsync

I wanted to keep things as simple as possible, so I used rsync. I created a /Library/WebServer/Documents/symfony2/app/config/rsync_exclude.txt file whose content is:

- app/cache/*
- app/logs/*
- web/.htaccess
- app/config/parameters.ini

I transfered the files using the rsync command on my local machine:

$ rsync -avz /Library/WebServer/Documents/symfony2 username@hostname:~/\

You could do something similar using sftp or even ftp. All you have to do is get your project directory onto your remote account. In my case, this means getting /Library/WebServer/Documents/symfony2 to ~/symfony2 .

Edit parameters.ini

I had to make changes to my app/config/parameters.ini file. As I am using Doctrine with a MySQL database backend, I needed to change my parameters to reflect those of the localhost. This is a pretty straight forward process and beyond the scope of this article to show you how to do this.

Create routing_prod.yml

I had to create a routing file for my production environment in app/config/. I copied “routing_dev.yml” to “routing_prod.yml” and took out any extraneous routes that I didn’t need for my production environment. You must be sure to remove the routes for:

I also needed to add the following lines to my app/config/config_prod.yml file:

    router: { resource: "%kernel.root_dir%/config/routing_prod.yml" }

so that the new routing parameters will be used by my app.

Console commands




After I made the changes to my configuration files, I needed to run some console commands to get everything working. Make sure that when you are running the app/console program that you do it from your main symfony2 project dir on your remote account.

First, I had to publish my assets

$ php app/console assets:install --symlink web --env=prod

Then I created the database that I referenced in my parameters.ini file with the command:

$ php app/console doctrine:database:create --env=prod

Finally, I had to update my schema so that the tables were created in the database for my models

$ php app/console doctrine:schema:update --force --env=prod

I had to use the “–force” option because app/console is hesitant to create tables in the production environment database.

That is all! If I missed a crucial step… please let me know so that I can update this post. Otherwise, happy hacking and good luck developing your Symfony 2 apps!

  1. Jacques said:

    don’t get the difference between these command lines:
    “First, I had to publish my assets

    $ php app/console assets:install –symlink web –env=prod

    Then I created the database that I referenced in my parameters.ini file with the command:

    $ php app/console assets:install –symlink web –env=prod

    Why doing this twice?

    • Thanks for noting this. I have updated the post with the correct command.

  2. jmborden said:

    hpatoio: Though I have since moved on to the Clojure Ring web stack for server development and don’t have time to test your bundle, this seems like a great tool for those who wish to deploy their Symfony2 project. Thanks!

  3. Marc said:

    You may want to check out our deploydo ( as a different approach to this. It takes care of the whole process and even shows you line-by-line comparisons, like in github, when updating code.

    • I would never use deploydo because it is non-free and I don’t want non-free tools dirtying up my toolchain, especially not for deployment. If I was to pay for a tool, I would invest in things like a compiler or something really cool like mocl, a Lisp for developing cross-platform iOS/Android apps.

      I also don’t like the fact that this introduces an extra layer of complexity to my workflow. One more thing to break, one more thing that will probably require some missing library after an upgrade, one more thing that I have to fix in order to get working right. Save yourselves the trouble people, stick to the scripts!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: