Some weeks ago I wrote about deploying Symfony2 Applications to Amazon AWS with Scalarium. It turned out that the described methodology can be improved in several ways. Here’s how.
First, let’s discuss what’s suboptimal with the previously described approach. The basic idea was to provide a custom Chef recipe which is executed on our instances whenever our Symfony2 application gets deployed. This recipe took care of
- executing the tasks which need to be done whenever the application is deployed, like installing the Symfony2 vendors or cleaning the application cache
- configuring Apache to correctly serve the application
Well, the problem is that these are really two very different tasks which shouldn’t be mixed together. Updating the web server configuration every time you release a new version of your application simply doesn’t make sense.
Thanks to Chef deployment hooks, we can separate these tasks. Whatever needs to be done upon application deployment can be provided within the application itself, making it much more self-contained. This way, application business logic and application deployment logic live in the same source tree.
On the other hand, system configuration steps which aren’t specific to deploying a new version of your application, but are specific to hosting your application in a given system context, shouldn’t be bundled with your application, but with your system context.
Thus, we are going to separate the deployment recipes and the system setup recipes. We will provide the deploy recipes from our application, and the system setup recipes through a custom Chef cookbook, just as we did in the first version of this tutorial.
Let’s look at the old version of our deploy.rb recipe, and decide which parts are related to the deployment of our application, and which parts are related to hosting our application.
Well, it’s actually quite simple – everything from the beginning of the file through line 44 is stuff that needs to be done upon every single deployment, or else we wouldn’t end up with a working application.
Let’s move this part of the deployment recipe into our application. Where does it belong? When Scalarium’s Chef deploys our application, it looks for certain scripts in the /deploy directory of our application:
For the steps we want to execute with our recipe (installing the vendors, clearing the app cache, executing db migrations, installing the assets, and chowning app cache and log dirs), the before_symlink.rb is just fine – it hooks into the deployment process the moment before Chef, after downloading the application source code from Github, changes the symbolic link at /srv/www/symfonyexample/current to the newly downloaded release. At this moment, we have all the source code available, but it is not yet put into production, thus it’s the most sensible moment for additional setup steps.
Moving the deployment-specific parts of our recipe into this hook gives us a before_symlink.rb script as it’s available in our ScalariumExampleSymfony2Application repository on GitHub.
The rest of the original recipe is all about configuring Apache in a way that gives us a working vhost for serving our application – this configuration may change, but it isn’t related to any specific deployment. Thus, these steps should be done only when our Scalarium/AWS instance is set up, and not on every deployment.
And as with the deployment steps, there is a better way to set up Apache for our application, too. Turns out, we don’t need a recipe at all. The reason is that Scalarium implements a very convenient substitution logic – if our own cookbook provides a file with the same name at the same location as one from the Scalarium-provided cookbooks, the file from our own cookbook “wins” and is used instead.
The Scalarium file we are going to substitute is located at /mod_php5_apache2/templates/default/web_app.conf.erb. By providing this file in our own cookbook repository, it’s used as the template for our Symfony2 application vhost – we don’t even need to define “symfony2::deploy” as a Custom Recipe anymore.
And that’s it. As described in my previous post on this topic, we need to configure our Scalarium cloud with the information on our custom cookbook and our application, but instead of manually hooking our custom recipe into the configure and deploy events in Scalarium, our newly created deploy hook now lives in the application itself, and is automatically triggered on every deployment, and our newly created web_app.conf.erb Apache vhost template is automatically used by Scalarium’s Chef when setting up new PHP application server instances.