How to Deploy Symfony Apps with Capifony

Share this article

Say you have a Symfony application. At some point, you would like to deploy it to your server and show it to the world. Of course, you can do it all manually, but these days you can also choose to use a tool like Capifony.

If you have developed Ruby applications in the past, you are perhaps familiar with Capistrano. Capistrano is a tool to deploy your Ruby application to your server. Capifony has been created on top of Capistrano, and is basically a collection of deployment recipes.

In this article, we are going to deploy a Symfony application to a server with Capifony.

How does Capifony work?

Before we start, it’s important to understand how Capifony works. By running the deploy command, Capifony runs certain commands performing different tasks. For example, it will download composer, install the dependencies and clear the cache.

The directory structure is very important. Capifony needs two directories and one symlink. The first directory it needs is called releases. Every time you deploy, a new directory is created within this directory. Capifony pulls in your git repository and runs all commands on this newly created directory.

The second directory is named shared. You can imagine that some directories are shared between releases. For instance, if you allow people to upload images, you want to make sure that these files are shared between releases. These directories and files are typically stored in the shared directory.

Next to these two directories, we have a symlink called current. This symlink points to the latest successful release. So, when you deploy a new version, a new directory will be created within the releases directory. If all tasks succeed on this directory, the current symlink will point to this new version.
You should point your web server to read from this symlink so it always uses the correct, latest version.

Installing Capifony

Let’s cut the theoretic part and dive into deployment. For that, we need to install Capifony. Make sure Ruby is installed on your system before proceeding. You can install the Capifony gem by running gem install capifony.

Within your application directory, run the command capifony .. This command will create a file named Capfile in your root directory and a deploy.rb in your configuration directory. You will alter the deploy.rb file during this article, so make sure you have it open in your favorite editor.

Now you have to decide what your deploy strategy will be. Either you choose to let your production server access your SCM (Source Control Management) or your local computer pulls in your repository from the SCM and copies it to your production server.

Within this article, we will look at the first strategy. If you are interested in the second strategy, have a look at the official Capifony website for instructions.

Configure your project

I am going to use this project and deploy it to a production server. I got the application checked out on my machine, so it’s time to run capifony ..

$ capifony .
[add] writing './Capfile'
[add] writing './app/config/deploy.rb'
[done] symfony 2 project capifonied!

When you open up the deploy.rb script, you will see the following content.

set :application, "set your application name here"
set :domain,      "#{application}.com"
set :deploy_to,   "/var/www/#{domain}"
set :app_path,    "app"

set :repository,  "#{domain}:/var/repos/#{application}.git"
set :scm,         :git
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `subversion`, `mercurial`, `perforce`, or `none`

set :model_manager, "doctrine"
# Or: `propel`

role :web,        domain                         # Your HTTP server, Apache/etc
role :app,        domain, :primary => true       # This may be the same as your `Web` server

set  :keep_releases,  3

# Be more verbose by uncommenting the following line
# logger.level = Logger::MAX_LEVEL

It’s time to change this configuration file. We start off with the top 4 parameters. First off, we define what the name of our application is, what the domain to deploy to is, what the directory will be and where the app path is. If you are using the default Symfony setup, the app path will already be configured correctly. So far my configuration looks like this.

set :application, "Jumph"
set :domain,      "peternijssen.nl"
set :deploy_to,   "/srv/www/jumph"
set :app_path,    "app"

Let’s configure our repository. Since we are using a git repository, we should set the SCM to git and point the repository to our Github repository.

set :repository,  "git@github.com:jumph-io/Jumph.git"
set :scm,         :git

Up next we define our model manager. In my case I am using Doctrine, but if you are using Propel, you should change the configuration value to “propel”.

We can skip the roles. They are just reusing your domain.

The last setting is the keep_releases setting. With this setting, you can define how many releases you may want to keep, allowing you to rollback to a previous version.

So far, we changed all the default config variables to the correct values. However, Symfony requires more configuration to be deployed. In my case, I am both using Assetic as well as Composer. This means I have to add the following settings to the file.

set :dump_assetic_assets, true
set :use_composer, true

Now we need to configure the shared files. For example, your parameters.yml should be shared between every release. Next to that, it’s wise to also share your uploads, your logs and your vendor between releases. If you are not sharing your vendor between every release, it means your deploy is installing all vendors every single time. To set these shared paths, we just add the following configuration.

set :shared_files,      ["app/config/parameters.yml"]
set :shared_children,     [app_path + "/logs", web_path + "/uploads", "vendor", app_path + "/sessions"]

Note that in my case I also moved the session directory outside the cache directory. This way I am able to share this directory between releases and nobody gets logged out on a new deploy. Do note you need to change the configuration within Symfony also to reflect this change.

session:
    save_path: "%kernel.root_dir%/sessions/"

Configure your server

So far everything is ready for our Symfony application. Now it’s time to configure everything for our server. We do this within the same config file as above.

When deploying, Capifony runs as root. If you prefer to run it as your own user, you can add the following lines to your configuration.

set :use_sudo,      false
set :user, "peter"

It’s also important to make sure your web server user is able to write to certain directories. This can be done by adding the following settings.

set :writable_dirs,       ["app/cache", "app/logs", "app/sessions"]
set :webserver_user,      "www-data"
set :permission_method,   :acl
set :use_set_permissions, true

Note: You might need to install certain packages on your server. For more information regarding permissions, please check this page.

Now we can tell Capifony to prepare the directories on your server. We can do this by running cap deploy:setup. Do make sure you have SSH access to the server and the directory is writable by your user of course.

Note: In my case I had to add default_run_options[:pty] = true to my configuration due to a known issue.

After the command has been run, you will notice it created the releases and shared directories on your server.

Now you should be able to deploy by running cap deploy on your command line. If you bump into any problems, you can add the following line to your configuration file, to get more information about the error.

logger.level = Logger::MAX_LEVEL

In my case, I was unable to access the git repository due to an invalid public key. Since my local computer can access the repository, I just had to forward my SSH agent to the server. This can be done by adding the following line to the deploy script.

ssh_options[:forward_agent] = true

Since it’s your first deployment, Capifony will ask you for the credentials of the parameters.yml file. You only have to fill them in once, since we configured the file to be shared across releases.

Adding additional commands

If you tried to deploy the repository I mentioned earlier, you will notice it fails when Assetic tries to dump it’s files. This is due to the fact that I am managing my JavaScipt and CSS dependencies through Bower. So before Assetic dumps the files, I should first run bower install.

Capifony by default has no support for bower, so we have to expand the list of tasks that Capifony performs. We add an additional task by adding it to the configuration file.

before 'symfony:assetic:dump', 'bower:install'

namespace :bower do
    desc 'Run bower install'
    task :install do
      capifony_pretty_print "--> Installing bower components"
      invoke_command "sh -c 'cd #{latest_release} && bower install'"
      capifony_puts_ok
    end
end

The task is quite easy to understand. First we define when the task should run. In this case, we want to run it before Assetic dumps its files. Next we define which task it should run.

The last thing we need to do is to define this new task. We do so by creating a task within a namespace and write down which command to run. In this task, we first make sure we are in the correct directory and then run bower install.

Additionally, I added some output before and after the command. This way, it will show up in the cap deploy command when running. It gives you some extra feedback as you can see below.

$ cap deploy
--> Updating code base with checkout strategy
--> Creating cache directory................................✔
--> Creating symlinks for shared directories................✔
--> Creating symlinks for shared files......................✔
--> Normalizing asset timestamps............................✔
--> Downloading Composer....................................✔
--> Installing Composer dependencies........................✔
--> Installing bower components.............................✔
--> Dumping all assets to the filesystem....................✔
--> Warming up cache........................................✔
--> Clear controllers.......................................✔
--> Setting permissions.....................................✔
--> Successfully deployed!

Additional commands

In the beginning, we decided to keep at least 3 releases. If something should go wrong in the new release, you can rollback by running the command cap deploy:rollback.

Additionally you can also activate or deactivate the Symfony maintenance page by either running cap deploy:web:disable or cap deploy:web:enable.

Capifony consists of more commands that might come in handy. For a full list you can run cap -vT.

Complete configuration

As a reference, this is the complete configuration file which we created through this article.

set :application, "Jumph"
set :domain, "peternijssen.nl"
set :deploy_to, "/srv/www/jumph"
set :app_path, "app"

set :repository, "git@github.com:jumph-io/Jumph.git"
set :scm, :git

set :model_manager, "doctrine"

role :web, domain
role :app, domain, :primary => true

set :use_sudo, false
set :user, "peter"

set  :keep_releases, 3

set :dump_assetic_assets, true
set :use_composer, true

set :shared_files, ["app/config/parameters.yml"]
set :shared_children, [app_path + "/logs", web_path + "/uploads", "vendor", app_path + "/sessions"]

set :writable_dirs, ["app/cache", "app/logs", "app/sessions"]
set :webserver_user, "www-data"
set :permission_method, :acl
set :use_set_permissions, true

ssh_options[:forward_agent] = true
default_run_options[:pty] = true

before 'symfony:assetic:dump', 'bower:install'

namespace :bower do
    desc 'Run bower install'
    task :install do
      capifony_pretty_print "--> Installing bower components"
      invoke_command "sh -c 'cd #{latest_release} && bower install'"
      capifony_puts_ok
    end
end

Conclusion

Capifony makes your life easier if it comes to deploying your Symfony application. Although we have already seen a lot of options Capifony offers, you might want to dig deeper. You can check out their website for more information. Are you using Capifony to deploy your Symfony applications? Let us know if you run into any difficulties or have any questions!

Frequently Asked Questions about Deploying Symfony Apps with Capifony

What is Capifony and how does it work with Symfony?

Capifony is a deployment tool specifically designed for Symfony and Symfony2 applications. It is built on top of Capistrano, a remote server automation tool. Capifony automates the process of deploying Symfony applications, making it faster and more efficient. It does this by automating tasks such as setting up permissions, clearing caches, installing vendors, and running database migrations.

How do I install Capifony?

To install Capifony, you need to have Ruby installed on your system. Once Ruby is installed, you can install Capifony by running the command gem install capifony in your terminal. This will install Capifony and its dependencies.

How do I configure Capifony for my Symfony application?

After installing Capifony, you need to configure it for your Symfony application. This involves creating a deploy.rb file in your application’s root directory. This file contains the configuration settings for your deployment, such as the server’s IP address, the deployment directory, and the repository URL.

How do I deploy my Symfony application using Capifony?

Once Capifony is configured, you can deploy your Symfony application by running the command cap deploy in your terminal. This will execute the deployment tasks defined in your deploy.rb file.

What are some common issues I might encounter when deploying with Capifony and how can I troubleshoot them?

Some common issues you might encounter when deploying with Capifony include permission errors, failed database migrations, and missing dependencies. To troubleshoot these issues, you can use the cap deploy:check command to check your deployment configuration and the cap deploy:pending command to see what changes will be made in the next deployment.

Can I use Capifony with other frameworks or languages?

Capifony is specifically designed for Symfony and Symfony2 applications. However, it is built on top of Capistrano, which can be used with any language or framework that can run SSH commands.

How can I automate the deployment process with Capifony?

Capifony allows you to automate the deployment process by defining tasks in your deploy.rb file. These tasks can include anything from setting up permissions to running database migrations.

How can I roll back a deployment with Capifony?

If something goes wrong during a deployment, Capifony allows you to roll back to a previous version of your application. You can do this by running the command cap deploy:rollback in your terminal.

How can I update my dependencies with Capifony?

Capifony can automatically update your dependencies during deployment. This is done by adding the symfony:composer:install task to your deploy.rb file.

How can I clear my cache with Capifony?

Clearing your cache is an important part of the deployment process. With Capifony, you can automate this task by adding the symfony:cache:clear task to your deploy.rb file.

Peter NijssenPeter Nijssen
View Author

Peter is a software architect from the Netherlands. He freelanced for more then 6 years as a web developer, and meanwhile, he graduated as software engineer with honors. He decided to join CMNTY Corporation which specializes in creating community software and is now responsible for the ongoing development of multiple web applications as well as mobile applications. Peter believes a real developer is able to combine multiple techniques together to make sure the user receives the ultimate experience and enjoys using the application. In his free time, he loves to play board games with anyone who is interested. He especially has a passion for cooperative board games.

asseticBowerBrunoScapifonydeploydeploymentframeworkOOPHPPHPsymfony
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week