Maybe you're interested About this site or in some of my Projects or Articles. You might even be interested About me or My Friends. If all else fails head back Home.

Morethanseven is where plays with the web

Symfony

How to deploy PHP sites with the Pake build tool

Monday, January 7th, 2008

So in case you hadn’t guessed project automation is the new black. I’ve been getting back into some development work recently with Is it Birthday? and getjobsin and trying to automate as much of the repetitive and boring work as possible.

I’m not absolutely sure that that many people outside large or particularly organised teams realise that large web sites are not generally deployed by someone with an FTP client and crossed fingers. This sort of effort, along with other repetitive tasks like running tests or generating documentation, can be automated. This is a win-win for everyone. It’s more reliable (scripts don’t forget to restart a service before they go home), quicker and removes the need for having one person in charge of deployments.

Even where people know about this build process idea they might not use it for their projects, probably for similar reasons why not everyone uses source control. I think the reason is probably that most web designers and developers (even particularly geeky ones) thing this software engineering stuff is maybe a step too far. Their is also something of a barrier to entry, knowing where to look and how to get started without reading lots of documentation (often filled with XML examples) and trial and error. Also project automation is apparently not sexy?

Anyway, if you’ve been working with Rails you will have come across Rake, which is a build tool used to automate various tasks. Well the nice symfony people have written a PHP version called Pake for use as part of the framework. It’s used for all the command line action, from running tests to clearing the cache and automating deployments. Pake is however a separate tool that you can use in your own projects, whatever framework or hand rolled codebase you are using.

Pake can be downloaded using PEAR on the command line:

pear upgrade PEAR
pear channel-discover pear.symfony-project.com
pear install symfony/pake

The documentation for Pake is pretty much non-existent as far as I can tell, but it is a really handy tool so worth a little effort. The best source of knowledge is to look through the default Pake tasks that are provided as part of symfony. One of my favourites, which we’ll look at now, allows for incremental deployments via Rsync over SSH. I’ve been using this with non-symfony projects too.

Rsync is a command line tool for syncronising two file structures. The Rsync command that does most of the heavy lifting for the deployment looks like the following. Note I’ve used {} to denote placeholders in the following examples.

rsync --progress --azC --force \
--delete -e ssh ./ {user}@{host}:{dir}

The sync task I’m using is straight from symfony, but the licence allows for distribution so here is an example zip of all the files needed to follow along. You’ll need these to follow along as I haven’t printed the full sourcecode for the pakefile here.

First a little configuration. Using YAML we define an environment, staging in this case_ and specify a host, port, user and the full path on the remote server. You can of course specify multiple environments in this file, we’ll see how to use them shortly.

[staging]
  host={host}
  port=22
  user={user}
  dir={dir}

You can also include an _rsync_exclude.txt_ or an _rsync_include.txt_ file. This gives you control over the files being synced when you run the Pake task. The following example is a good starting point, it stops you pushing those pesky .DS_Store files that OSX creates to you web server, as well as avoiding subversion metadata and the configuration files for the Pake task.

.svn
.DS_Store
/config/properties.ini
/config/rsync_exclude.txt
/config/rsync_include.txt
/config/rsync.txt

We can now run the following command, from the directory containing the pakefile.php script, using Pake. The first example will do a dry run, showing you what will happen. You’ll be prompted for your SSH password as part of the command unless you’re using keys for authentication.

pake sync staging

When you’re happy you can run the sync command with the go option which will instruct Rsync to do it’s thing.

pake sync staging go

Pake has a handy flag to find out what tasks are available.

pake -T

This should give you a list of tasks and a brief description, useful to find out what you can do if you’ve been away from a project for a while.

This is a pretty simple example but one I’m already finding useful. Rsync is but one way of deploying apps but with Pake has the advantage of being simple and in lots of situations good enough. It’s certainly better than a manual deployment process. It would be simple enough to build into the task a simple logging system so you have a log of all deployments; when they happened and who did them for instance.

If that has whet your appetite then their are other deployment tools you might want to look into; Capistrano (Ruby), Ant (Java), Maven (Java) and Phing (PHP) spring to mind. If anyone knows of a Python equivalent that would be useful too? I’m also using Phing for a few tasks on projects at the moment, mainly for some nifty Subversion tasks (and you can use Phing with Pake as symfony does), but that will have to wait until another post.

So, what are peoples experiences of build tools? Any good pointers? Or maybe reasons why you don’t use them in your projects?

Popularity: 16%

Tagged , , , , , , , ,

Is it Birthday?

Friday, December 28th, 2007

Did you love the simplicity of Is it Christmas? but feel left out, wondering why Christmas should be more important than, say, you? Well here’s your answer; Is it Birthday?

Is it Birthday? home page

Popularity: 9%

Nice bits of symfony: Web Debug Toolbar

Wednesday, December 26th, 2007

I mentioned previously that I’d been playing with the symfony framework on a couple of projects and I have to admit to being more and more impressed as I wade in looking for things. I’ve worked with enough MVC-like frameworks to know they are all quite similar in more ways than they are dramatically different. So it’s the little bits and pieces that win you over.

One of my favourite little bits in symfony has to be the Web Debug Toolbar. When running in development mode you get a little menu floating above your application like so (top right hand corner).

Web page showing the symfony web debug toolbar in the top right corner

This gives you all sorts of useful information as you’re developing your application – from the number of database queries to the rendering time, with a full logger built in. It’s also been particularly useful in learning symfony – being able to follow the entire request through the stack from the logger is really handy when you don’t know what is going on.

Web page showing the symfony web debug toolbar fully expanded

With the increasing use of object relational mapping in web frameworks it’s quite easy to end up with a working application on your development box that turns out to absolutely hammer your database when used in the real world by only a few hundred people (I’m looking at you tagging). The database utilities, showing the number of queries and the SQL for those queries, is particularly handy for finding bottlenecks here.

Web page showing the symfony web debug toolbar SQL view

I’ve not come across something similar in other frameworks, PHP or otherwise. I’d be interested to know if similar things do exist for Rails or Django in particular.

Popularity: 9%

Tagged , , ,

Getting going with Symfony

Sunday, September 16th, 2007

I’ve tinkered with a rather large number of these web application frameworks, in Ruby, Python, PHP and C#, at some point over the last few years. But I’ve never really settled on any of them – mainly because my day job didn’t need me to and also because I like playing with new toys. I even tinkered with my own homage to Web.py in PHP which a few people have picked and are running with.

Right now though I’ve been doing some work with a few people on a Rails project. Their are some seriously nice things in Rails that I don’t see elsewhere; really good testing support baked in for one, and some serious deplyments for another.

Symfony is another PHP framework but one that only supports PHP5 (a good thing in my book). It’s basically a slick integration of lots of existing mature PHP tools plus some good old MVC and tried and trusted Software Patterns. I also discovered from a few YAHOO’s that they have started using it on some levels within YAHOO.

My interest piqued I found a couple of related presentations on Slideshare (my new favourite web app), and the site has a high quality online documentation which can also be purchased in dead tree format.

Having a play around with Symfony it took me a little while to get everything up and running, but I’d kept some handy notes for later. Hopefully they might be useful to someone other than me.

I’ve dropped in a few variables denoted by braces where relevant. The paths are from my MAMP and PEAR based environment and I’m using a MySQL database, though you could just as easily use Sqlite.

First we set up a virtual host in Apache. You have to do this manually at the moment. I already have a script for setting up virtual hosts under apache on OS X which I might extend to do this for me if I end up using Symfony alot.

<VirtualHost 127.0.0.1>
  ServerName 
  DocumentRoot "/Applications/MAMP/htdocs/{project}/web"
  DirectoryIndex index.php
  Alias /sf /Applications/MAMP/bin/php5/lib/php/data/symfony/web/sf
  <Directory "/Applications/MAMP/bin/php5/lib/php/data/symfony/web/sf">
    AllowOverride All
    Allow from All
  </Directory>
  <Directory "/Applications/MAMP/htdocs/{project}/web">
    AllowOverride All
    Allow from All
  </Directory>
</VirtualHost>
cd /www
mkdir {project}
cd {project}

Now we dive into the actual symfony commands. We’ll just setting up both a frontend and a backend for this app which I think is likely to be pretty typical. I quite like the idea of seperate entities for these.

symfony init-project {project_name}
symfony init-app frontend
symfony init-module frontend {module_name}

Next we have to configure our database connection by editing /config/databases.yml

all:
    propel:
      class: sfPropelDatabase
      param:
        dsn: mysql://{username}:{password}@localhost:3306/{database_name}

That done we can set up our data definitions in /config/schema.yml. Read the documention for all the details but you can probably get the general idea.

propel:
item:
  id:
  title: varchar(200)
  description: longvarchar
  created_at:

And yet another quick change in /config/propel.ini

propel.database.createUrl = mysql://{username}:{password}@localhost:3306
propel.database.url = mysql://{username}:{password}@localhost:3306/{database_name}

The next set of commands build our model files, create SQL for out chosen database and then create the tables in the database.

symfony propel-build-model
symfony propel-build-sql
symfony propel-insert-sql

We’ll quickly create a backend using the scaffolding. Note that item here is the model name which is taken from the schema.yml config file above.

symfony init-app backend
symfony propel-generate-crud backend items Item

All in all not bad going. And that’s basically the same for most of the apps you’re likely to develop. It could probably be a little easier in the database and apache config areas in fairness. Rails’ use of an inbuild webserver really helps here. But the use of YAML to define the model is, in my mind, more straightforward that using Ruby in Rails migrations. I’ve an app in the works at the moment and I’m looking at using Symfony. If that pans out I’ll blog more about the bits I’m interested in – the inbuilt unit testing framework high on my list.

Popularity: 9%

Tagged , , , , ,