PHP conferences update

There are some great conferences around the PHP world that are coming up or are being announced. Here is the list (if we missed one, please let us know)

  • Open Source India – September 19-21, 2010 – Chennai, India
  • PHP Matsuri – October 2-3, 2010 – Tokyo, Japan
  • Symfony Day Cologne 2010 – October 8, 2010 – Cologne, Germany
  • ZendCon – November 1-4, 2010, Santa Clara, California
  • Symfony Live San Francisco – February 2011, San Francisco, California
  • Symfony Live Paris – March 3-5, 2011 – Paris, France



As always, if you work around PHP, we encourage you to participate of conferences which are an invaluable tool to enhance your skills and meet with fellow developers and colleagues.

31

08 2010

Zend Framework 1.10.8 released!

Today the Zend Framework development team announced the availability of Zend Framework 1.10.8 which includes around 22 bugfixes. For a complete changelog, go here.

As previously, it is noted that those users that depend on ZF for their twitter connected applications upgrade immediately to 1.10.8 to ensure that you use the OAuth functionality required by Twitter.

This release is already available in all our servers for our customers. For more information about our Zend Framework hosting offering, click here.

25

08 2010

Fixing problems in Apache with case-sensitive URLs

Windows or Mac servers treat file names as case-insensitive, so Index.html and index.html are the same file. In Linux/Unix servers this is not the case, these files would be different. So when we create a link that does not match the case of the file name, you get an error. This is a common problem when moving files from Windows/Mac to a Linux production server and your links include incorrect case.

The ideal solution is to go over the entire site and correct these mismatches. But this may take some time and usually one finds out about the problem when the site has been moved and the domain pointed to the new server, so the problem has to be fixed ASAP.

There is a quick solution thanks to Apache’s mod_speling. If you need Apache to check different versions of a file name requested, you can use CheckCaseOnly and CheckSpelling directives. Adding one of these directives in a .htaccess file in the root directory of your site instantly fixes most of these problems. An example of this configuration is:

CheckSpelling on

We need to note that this method delivers a performance hit. Apache will have to double check each request for spelling when it does not find the file right away. So let it be noted that this is a quick fix; long term it is recommended that you backtrack and correct all the links.

24

08 2010

New OS images available for VPS plans

We have some new images available and tested for VPS servers. These are available as an upgrade or you can select the image you want when you order.

  • Ubuntu 10.04
  • CentOS 5.5

On both OSes, you can choose 32 or 64 bit with PHP 5.3 or PHP 5.2 (always the latest version); or you can choose a standard installation with no custom packages.

We have also upgraded numerous packages inside the custom installations and have included MongoDB support for PHP.

If you want to upgrade your existing VPS to one of these images, open a support ticket. Some versions can be upgraded without needing to reinstall the entire VPS, but this is not always the case.

16

08 2010

SSH strange error: Host key verification failed

Today we came across a quite uncommon error with SSH. The error actually happened when trying to clone a github repository. When trying to connect to the remote server, we were getting “Host key verification failed.”. The SSH keys were there, but the connection was dying.

The problem was solved when adding the remote server’s key to the .ssh/known_hosts file, but why didn’t ssh add the key to this file automatically as it always does? Well, this was happening inside a CHROOT environment, so more debugging was needed.

After running the ssh git@github.com command with strace, we noticed that the /dev/tty device file did not exist, and the ssh commands could not prompt us to confirm that we wanted to add the key to the known_hosts file. The solution was quite simple, copy the /dev/tty device file to the dev directory of the CHROOT environment. After this, everything worked as expected.

Tags: , , ,

02

08 2010

Zend Framework 1.10.7 released!

Late last week, the Zend Framework development team announced the availability of Zend Framework 1.10.7 which includes around 60 bugfixes. For a complete changelog, go here.

It is noted that those users that depend on ZF for their twitter connected applications upgrade immediately to 1.10.7 to ensure that you use the OAuth functionality required by Twitter.

This release is already available in all our servers for our customers. For more information about our Zend Framework hosting offering, click here.

02

08 2010

PHP 5.2.14 and 5.3.3 released and available at ServerGrove!

The PHP core team yesterday released new versions of the popular PHP language. The new versions are 5.2.14 and 5.3.3 and feature lots of bug and security fixes. Release notes are available for 5.2.14 and 5.3.3.

These versions are already available in new VPS deployments. If you want PHP upgraded to these versions in your current ServerGrove VPS, please open a ticket and we will upgrade it. Our upgrade policy for Shared hosting servers is to wait a reasonable period of time before applying the upgrade, unless there is a big security fix. This waiting period is necessary to make sure there are no big bugs in the new version, as we have experienced issues in the past with new versions and Shared hosting customers.

23

07 2010

ServerGrove is moving to the NAP of the Americas

We have some amazing news to share with our current and future customers as we continue to grow!

We just signed our agreement and will be moving our servers to Terremark’s NAP of the Americas in September; storing your data in one of the top datacenters in the country and the world. You will be in good company, it’s the same datacenter used by the US Govt’ and many of the major banks and telco companies.

NAP of the AmericasThe datacenter is designed to withstand and continue normal operation even if a category 5 hurricane (the strongest of hurricanes) hits the area.  It offers unrivaled n+2 redundant power and cooling. Apart from the military grade security and impressive power redundancy, the NAP of the Americas has direct backbone access as it sits on one of the most important network access points in the planet offering a direct connection to over 148 countries in the world. Miami has been ranked as one of the top-five best interconnected cities in the world, ahead of San Francisco, Chicago and Washington, D.C. Terremark’s NAP of the Americas makes Miami the only city in the U.S. where Optical, Ethernet, MPLS, Voice and Internet traffic is handed off in a single location, and we are on it!

So seriously, apart from these awesome reasons, why are we switching?

First of all, our current datacenter offers only a single carrier. They are awesome and have been good to us, but as a rule of thumb we like to build in redundancy into our systems. When we switch to Terremark we will have three network providers: AT&T, Verizon Business and Level3. Needless to say, three is better than one and we know that we will not loose connectivity. In addition, we will be sitting directly on top of their network access point with direct backbone access; minimizing the hops your data packets have to take. In sum, we will be providing some of the best kick-ass connectivity out there.

Will our current clients move too?

Absolutely! Between September and November we will be moving all our clients to our new Datacenter and in the process we will be upgrading some of our hardware. We don’t expect any downtime and all our clients will get an email informing them of the migration process when the time comes.

If you want to learn more about Terremark and the NAP of the Americas, feel free to visit their website at: http://www.terremark.com/technology-platform/nap-of-the-americas.aspx

16

07 2010

Symfony + Git + Capistrano = Capifony

Introduction

Deploying applications to production/live servers is always a delicate task. The whole process needs to be quick to minimize downtime. Automating the deployment process helps running repetitive tasks minimizing the possibility human error. It is also a good idea to have a proven and easy way to rollback to a previous version if something goes wrong.

Capistrano and more specifically Capifony can help with the automatic deployment of symfony projects.

What is Capistrano?

Capistrano is a time saving command line tool, written in Ruby, that helps you execute automated tasks on remote servers from your local environment. It also allows you to run symfony commands. Capistrano was built to help you administer all your servers from one place, running commands, installing software and keeping everything in sync. Oh… and of course it has a rollback mechanism.

It’s one of those tools Ruby developers have that we often wish we had in symfony, and now we do. Enter Capifony…

Capistrano commands

Capistrano has 2 base commands:

1. `capify …`;
2. `cap …`.

Capify will create 2 files in a specified path (1st argument of `capify`):

1. `Capfile` – capistrano loader. It loads all basic libraries & project config file;
2. `config/deploy.rb` – project config file. Your configs & variables setup for project placed here.

The second command, `cap`, actually runs capistrano tasks on the remote server with config from your `config/deploy.rb`.

A capistrano recipe is a package of tasks, grouped into namespaces. You can use embedded tasks or write your own (place them in your `config/deploy.rb`). Once a task is written you can run it with `cap` command under your project directory:

cap namespace:task

Deployment recipe
—————–

As mentioned above, Capistrano is typically used to deploy Ruby On Rails applications. How does it work? Basically, capistrano must know 4 things:

1. addresses of your web, app & db servers (most often it’s the same address);
2. address of your source code control system repository (if you have one).

Keep in mind, that capistrano uses SSH to run remote tasks so you will need to have shell access to all your remote servers.

During the deploment process, Capistrano will maintain different files & directories on server. It will create a `releases` directory that has dated directories with the actual copy of your code for each release. In addition, Capistrano symlinks your shared folders (common between releases) into release directories, so logs, assets & other files keeps the same between deployments.

What is Capifony?

Capifony is a new RubyGem package, that extends Capistrano functionality so it can work with symfony PHP projects. In essence it’s a package of custom and extended original capistrano recipes.

Demo project

To fully understand how capifony works and what it does we need to create one simple symfony application and deploy it to our test server.

Step 1: Install

I assume that you already have Ruby & RubyGems installed on your local environment (MacOS X has this out of the box – simply update gems with `sudo gem update –system`).

To install capifony and capistrano, simply run:

gem install capifony

This command will install capifony and it’s dependencies (capistrano for example) to your local host. NOTE: Your local host is the only place where you need to install capifony & capistrano.

It’s also good practice to create and copy the SSH key to speed up the connections to your remote repositories.

Generate key with:

ssh-keygen -t rsa

Next, copy your public key to remote server that you want to connect to (I am going to assume your SSH user is called `demoUser`):

cat .ssh/id_rsa.pub | ssh demoUser@your.domain.com "cat >> .ssh/authorized_keys2"

Then just try to connect with:

ssh demoUser@your.domain.com

If all goes well the remote server will just let you in without password prompt.

We then need to create the project repository on server, so let’s create one:

ssh demoUser@your.domain.com
sudo mkdir /var/repos
sudo chown demoUser !$
cd !$
mkdir demo.git
cd !$
git --bare init

Step 2: Symfony project setup

Lets create empty git repository for our new demo site (we will use git as SCM, but you can use subversion or any other source code manager that’s supported by capistrano):

cd /var/www
mkdir demo
cd !$
git init
touch .gitignore

Now add these lines to your `.gitignore` to exclude asset symlinks, databases config, cache, backups, uploads & log folders from our git repository:

web/sf*
web/uploads/*
cache/*
plugins/.*
log/*
config/databases.yml
mkmf.log
.rsync*
backups/*

It’s time to add `.gitignore` to stage and make our initial commit:

git add .gitignore
git commit -m 'initial commit'

Finally we can generate skeleton for our demo project and commit it:

symfony generate:project demo
git add .
git commit -m 'symfony project created'

Now lets add the database schema to `config/doctrine/schema.yml`:

	---
	Topic:
	  actAs:
	    Timestampable:    ~
	  columns:
	    id:
	      type:           integer(4)
	      primary:        true
	      autoincrement:  true
	    title:
	      type:           string(256)
	      notnull:        true
	    content:
	      type:           clob
	      notnull:        true

And add some fixtures into `data/fixtures/fixtures.yml`:

	Topic:
	  topic1:
	    title:    First topic
	    content:  first topic content
	  topic2:
	    title:    Second topic
	    content:  second topic content
	  topic3:
	    title:    Third topic
	    content:  third topic content

Build database and model files:

symfony doctrine:build --all --and-load --no-confirmation

And you need to generate the `frontend` application and put `main` module in it:

symfony generate:app frontend
symfony generate:module !$ main

To make this more interesting let’s put some logic for our application. Go to `apps/frontend/modules/main/actions/actions.class.php` and replace the `executeIndex` function code with this:

/**
* Executes index action
*
* @param sfRequest $request A request object
*/
public function executeIndex(sfWebRequest $request)
{
   $this->topics = Doctrine::getTable('Topic')->findAll();
}

And the view. Go to `apps/frontend/modules/main/templates/indexSuccess.php` and add:

<dl>
  <?php foreach ($topics as $topic): ?>
    <dt><?php echo $topic->getTitle() ?></dt>
    <dd>
        <?php echo $topic->getContent() ?>
    </dd>
  <?php endforeach; ?>
</dl>

Now if you open http://your.local.demo.host/frontend_dev.php/main in browser you will se definition list with our 3 topics.

Add changes to git:

git add .
git commit -m 'finished project'

Stage 3: symfony library with project

It’s good practice to include the dependent version of symfony in your project repository. You can do this in two ways:

1. Simply copy symfony library under `lib/vendor/symfony` directory & commit it;

or

2. Submodule symfony library from another repository.

I like second way. To do this, we will submodule Vincent Jousse’s symfony 1.4 git mirror:

git submodule add http://github.com/vjousse/symfony-1.4.git lib/vendor/symfony

Don’t forget to fix symfony path in `config/ProjectConfiguration.class.php` (after both ways) from:

require_once '/opt/local/lib/php/symfony14/lib/autoload/sfCoreAutoload.class.php';

to

require_once dirname(__FILE__) . '/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';

And commit this:

git add .
git commit -m 'bundled symfony'

Step 4: Push local project to remote git repository

Remember our `demo.git` repository on `demoUser@your.domain.com` that we’ve created earlier? It’s time to push our project to it:

git remote add origin 	ssh://demoUser@your.domain.com/var/repos/demo.git
git push origin master:refs/heads/master

Now your project is pushed to remote repository, where anyone who has SSH access can push/pull it. Also, we will use this repository to deploy new versions with capistrano.

Step 5: Config

Now is the time to play with capifony itself. First of all, lets “capifony” our project:

capifony .

Capifony created `Capfile` and `config/deploy.rb`. Go into `config/deploy.rb` and edit it’s variables. To set capistrano config variables, you need to call `set :var_name, “var_value”` instruction inside `deploy.rb`. Below is the list of main variables:

* `:application` – set your application name here (“demo” in our case);

* `:domain` – domain of our remote server. This variable will be auto-populated with `#{application}.com` (demo.com in our case). Place your server address here if it’s not `demo.com`. I set it to `#{application}.everzet.com`, because my test host is http://demo.everzet.com;

* `:deploy_to` – path, where we will deploy our application (in most cases `/var/www/#{domain}`);

* `:repository` – path to repository (`#{domain}:/var/repos/#{application}.git` in our case);

* `:scm` – source code management tool. In our case set it to `:git`, but it can be any of `accurev`, `bzr`, `cvs`, `darcs`, `subversion`, `mercurial`, `perforce`, `subversion` or even `none`;

* `:use_sudo` – set to `false`, because we doesn’t need sudo during our deployment process;

* `:deploy_via` – set it to `:remote_cache`, so deployments will last less time;

* `:git_enable_submodules` – set it to `1` if you have submodules in project (if you staged symfony as submodule for example);

Also add this line to `config/deploy.rb`:

ssh_options[:forward_agent] = true

if you want to use your local SSH key instead of remote one for git checkout.

Your resulting `config/deploy.rb` is must be something like this:

set  :application,            "demo"
set  :domain,                 "#{application}.everzet.com"
set  :deploy_to,              "/var/www/#{domain}"

set  :scm,                    :git
set  :git_enable_submodules,  1
set  :repository,             "#{domain}:/var/repos/#{application}.git"
set  :deploy_via,             :remote_cache

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

set  :use_sudo,               false
set  :keep_releases,          3
ssh_options[:forward_agent] = true

Step 6: Deployment

To start, we need to know 3 basic capistrano commands:

1. `cap deploy:setup` – create directories on server;
2. `cap deploy:cold` – copy code, build database, make symlinks;
3. `cap deploy` – copy code, make symlinks.

Now run:

cap deploy:setup

This command will create the following folder structure on your server:

	`-- /var/www/demo.everzet.com
	  |-- releases
	  `-- shared
	    |-- log
	    `-- web
	      `-- uploads

After few deployments, folder structure will eventually become something like this:

	`-- /var/www/demo.everzet.com
	  |-- current (symlink)
	  |-- releases
	    |-- 20100512131539
	    |-- 20100509150741
	    `-- 20100509145325
	  `-- shared
	    |-- log
	    |-- config
	      `-- databases.yml
	    `-- web
	      `-- uploads

What does all this mean?

1. `releases` is folder, where all your releases sits. Every release is a timestamped folder under `releases` directory.

2. Every release has symlink to shared files and folders, placed in `shared` directory. This files & folders stays same between deploys;

3. capistrano creates symlink to latest release, called `current`. This is your current project folder to work with (where to point web servers, crontabs etc.).

Now lets deploy our application for the first time:

cap deploy:cold

If you’ve configured your remote server hosts right, you now can open http://your.remote.host/main & see you symfony application there.

Step 7: Deploy & Rollback

Now what if we change something, deployed it and it’s broke our site? Lets break something!

Open `apps/frontend/modules/main/actions/actions.class.php` and change

$this->topics = Doctrine::getTable('Topic')->findAll();

to

$this->topics = Doctrine::getTable('TopicS')->findAll();

Save it, commit it and push to remote repository:

git add .
git commit -m 'buggy change'
git push origin master

Now deploy this bug:

cap deploy

and try to open http://your.remote.host/main. Oh, no! Something broke. What to do? Simple! Run:

cap deploy:rollback

and capistrano will roll your server back to previous working version of project and you will be able to find, fix, push and deploy the bugfix later, without problems.

Conclusion

Capistrano is mighty tool that has served RoR developers for many years. Now the symfony world can use these best practices in their development workflow. It’s as simple as installing capifony gem.

If you want to add/request something or read further manuals – please, visit project repository on github.


About the Author

Konstantin Kudryashov (aka everzet) is a web developer from Minsk, Belarus. Most of the time, he builds symfony applications. When he’s not – he maintains symfony bundles for TextMate, writes symfony plugins & php libraries.

12

07 2010

Zend Framework 1.10.6 released!

The Zend Framework development team announced the availability of Zend Framework 1.10.6 which includes over 30 bugfixes. For a complete changelog, go here.

This release is already available in all our servers for our customers. For more information about our Zend Framework hosting offering, click here.

29

06 2010