Deploying symfony project with Capistrano
May 12th, 2008
As you may know Capistrano is a great tool "originally written to ease the pain of deploying Rails applications". If you are not familiar with it take a look at it's getting started guide.
Even if Rails applications development is the primary way that people use Capistrano it can be used for a lot more than that.
Let me show you how you can use it for easy-and-with-no-pain deployment of symfony project.
First cd to your project and run (I assume that you have Capistrano installed allready)
$ capify . |
So this is how the modifed deploy.rb file that I use to deploy my symfony projects looks like :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
set :application, "mysfapp" set :repository, "http://path/to/the/version/control/repository" # If you aren't deploying to /u/apps/#{application} on the target # servers (which is the default), you can specify the actual location # via the :deploy_to variable: set :deploy_to, "/path/to/project/#{application}" # If there's no access to the repository from the production server, deploy via uploading tarball to the server #set :deploy_via, :copy # If you aren't using Subversion to manage your source code, specify # your SCM below: # set :scm, :subversion role :app, "codingspree.net" role :web, "codingspree.net" # role :db, "your db-server here", :primary => true set :user, "codingspree" # path to php executable set :php, "/usr/local/php5/bin/php5" # symfony application name (used for migrations) set :sf_app, "frontend" namespace (:deploy) do desc <<-DESC [internal] Overriding original task to fit to symfony project needs DESC task :finalize_update, :except => { :no_release => true } do run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true) run <<-CMD rm -rf #{latest_release}/log && ln -s #{shared_path}/log #{latest_release}/log CMD run <<-CMD rm -rf #{latest_release}/cache && ln -s #{shared_path}/cache #{latest_release}/cache CMD stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S") asset_paths = %w(images css js).map { |p| "#{latest_release}/web/#{p}" }.join(" ") run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" } end desc <<-DESC Overriding original task to exclude restart DESC task :default do update end desc <<-DESC Overriding original task to use symfoy migrations (via sfMigrationsLightPlugin) DESC task :migrations do update sf.migrate end after "deploy:update", 'deploy:customize' desc <<-DESC All custom tasks will be here DESC task :customize do # custmize it here sf.symlinks sf.remove_dev_environments # clear cache sf.cc end end namespace (:sf) do desc <<-DESC Run the "symfony migrate" task DESC task :migrate do run "cd #{current_path} && #{php} symfony migrate #{sf_app}" end desc <<-DESC Run the "symfony cc" task DESC task :cc do run "cd #{current_path} && rm -rf cache/*" end desc <<-DESC Create symlink to symfony specific targets DESC task :symlinks do # symlink to database.yml run "rm -rf #{current_path}/config/databases.yml" run "ln -s #{shared_path}/databases.yml #{current_path}/config/databases.yml" # symlink to config.php run "rm -rf #{current_path}/config/config.php" run "ln -s #{shared_path}/config.php #{current_path}/config/config.php" # symlink to sf data dir run "rm -rf #{current_path}/web/sf" run "ln -s /path/to/sf/data/dir #{current_path}/web/sf" # symlink to uploads run "rm -rf #{current_path}/web/uploads" run "ln -s #{shared_path}/uploads #{current_path}/web/uploads" end desc <<-DESC Remove DEV environments DESC task :remove_dev_environments do run "rm -rf #{current_path}/web/*_dev.php" end desc <<-DESC Disable symfony application DESC task :disable do run "cd #{current_path} && #{php} symfony disable #{sf_app} prod" end desc <<-DESC Enable symfony application DESC task :enable do run "cd #{current_path} && #{php} symfony enable #{sf_app} prod" end end |
1 2 |
# path to php executable set :php, "/usr/local/php5/bin/php5" |
1 2 |
# symfony application name (used for migrations) set :sf_app, "frontend" |
In the next section of the deploy.rb file I overrided few of the original tasks from deploy namespace to fit to my needs - finalize_update to set symlinks to symfony cache and log directories, the default task to exclude restart because I don't need it, migrations to set it to use symfony migrations and at the end there is one hook task that will be executed after deploy:update -it's called customize and I'll place all custom tasks there.
The last part of the file is sf namespace that includes some symfony related tasks as migrate, cc, symlinks, remove_dev_environments, disable, enable and so on. As you see you can wrap any symfony task that you have to execute on the production server with Capistrano task.
All you need now is to set a little bit the production server (run cap deploy:config, symlink document root to /path/to/project/mysfapp/current, place relevant database.yml and config.php in /path/to/project/mysfapp/shared, etc) and you are ready to run
$ cap deploy |
2 comments »

Hi, my name is Krasimir Angelov. I'm working as web developer.