Mini Hosting Special

We are making the Mini available for $20 a year (regular price is $35) for the first 50 clients who sign up for the Mini using the coupon code “minifor20

For $20 a year you get:

200mb disk space
1 hosted website
3GB bandwidth
1 MySQL database
10 email accounts
Maestro

Use the COUPON CODE: “minifor20” when you sign up.

08

02 2010

Setting up subdomain virtual hosts for multiple applications in a symfony project

It is very common to have multiple applications in one symfony project, like frontend, backend, api, etc. The common way to access the application is by specifying the application front controller, like

  • http://example.com/frontend.php
  • http://example.com/backend.php
  • http://example.com/api.php

Most of the time, it is nicer and better to use subdomains, like:

  • http://www.example.com/
  • http://backend.example.com/
  • http://api.example.com/

There are some hacks (here, here and here) on the net that allows you to define the application and environment based on the domain. These are good options if you need something quick and do not want to mess with the web server configuration, but you lose some flexibility and specially, all the web server log entries end up in a single file. I think it is better to have the traffic go into separate files for reporting and debugging purposes.

You can accomplish this by setting up virtual hosts for each subdomain and define the front controller for each virtual host.

1) setup the DNS entry. The recommended way is to setup a CNAME record. If you have a A record that points your domain to the IP addresss (example.com A 1.2.3.4) then you can setup a CNAME record which will point your subdomain to the same IP address without having to specify the IP in each subdomain. Then if you need to change your IP address, you just change it in one location:

example.com. A 1.2.3.4
backend.example.com. CNAME example.com.
www.example.com. CNAME example.com.
api.example.com. CNAME example.com.

You can also define a wildcard DNS like:

*.example.com. CNAME example.com.

This will make any-subdomain.example.com point to your IP address.

2) once you have your DNS records in place, it is time to configure the web server. If you use Apache, you would setup several virtual hosts like the following:

<VirtualHost *:80>
DocumentRoot /usr/local/sfproject/web
ServerName backend.example.com
ErrorLog logs/backend-error_log
CustomLog logs/backend-access_log common

<Location />
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /backend.php [L]
</IfModule>
DirectoryIndex backend.php
</Location>

</VirtualHost>

<VirtualHost *:80>
DocumentRoot /usr/local/sfproject/web
ServerName www.example.com
ServerAlias example.com
ErrorLog logs/frontend-error_log
CustomLog logs/frontend-access_log common

<Location />
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /frontend.php [L]
</IfModule>
DirectoryIndex frontend.php
</Location>

</VirtualHost>

<VirtualHost *:80>
DocumentRoot /usr/local/sfproject/web
ServerName api.example.com
ErrorLog logs/api-error_log
CustomLog logs/api-access_log common

<Location />
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /api.php [L]
</IfModule>
DirectoryIndex api.php
</Location>

</VirtualHost>

Notice that the mod_rewrite rules that usually are included in a .htaccess file are directly specified in the virtual host. If you disable .htaccess files and specify this configuration in your virtual hosts, your web server will gain some speed. If you prefer to use .htaccess files for convenience, you can have multiple .htaccess files and define which file to use in each virtual host using the directive AccessFileName.

Notice how I linked all virtual hosts to the same symfony project, and defined the default page and mod_rewrite to point to each front controller.

3) restart your web server and test.

In order to setup something like this, you will need to have full access to your environment so it is only possible to accomplish in a VPS or dedicated server. This functionality is planned for the next release of Maestro for shared hosting.

08

02 2010

Enhance your date input fields in symfony forms

Symfony’s forms are very powerful and big time-savers. Also, thanks for the integration with an ORM like Doctrine or Propel, managing dates is quite easy. But by default, symfony displays date fields as regular select lists where you pick the date (month, day, year, hour, minute)

It is actually quite easy to enhance this functionality and display a friendlier way to pick a date. There are several options at your disposal:

sfFormExtraPlugin

The sfFormExtraPlugin plugin has numerous widgets to improve the appearance and functionality of form input fields. One of them is sfWidgetFormJQueryDate which displays a button next to your field. When clicking on it, a date picker calendar-style pops up.

Note: You will need to download the jquery theme to make it look pretty.

To use it, simply install the plugin and add the following to your form configure() method:

        $this->widgetSchema['publish_at']= new sfWidgetFormJQueryDate();

Also, make sure you load the jquery javascript files in view.yml:

  javascripts:
    - http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
    - http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js

sfJQueryUIPlugin

The sfJQueryUIPlugin plugin is a nicer option. It displays a date picker when you click on the date input field, but it still allows you to modify it manually.

Installation is also quite easy. Install the plugin and add the following to your form configure method:

        $this->widgetSchema['publish_at']= new sfWidgetFormDateJQueryUI(array('change_month' => true, 'change_year'=> true));

Unobtrusive Datepicker

The Unobtrusive Datepicker by Massimiliano Arione is probably the nicer of the options, but also the less straightforward as there is no aparent plugin for it yet.

Follow the instructions on the site to get it working.

Any others?

Have you found any other solutions? Let us know and share it with us!

04

02 2010

What Facebook’s HipHop means for PHP-based applications hosting

Today Facebook revealed what they have been working behind the scenes for a long time. In a nutshell, HipHop is aimed at improving PHP’s performance by converting PHP code to C++ and then compiling it with g++, thus allowing Facebook to keep up with their growth with fewer servers.

In theory, by running compiled code, users would get major gains in performance with the same hardware. This is specially true for applications and sites built using frameworks like Symfony, Zend Framework, Cakephp and others. But it also means that you will need to compile the PHP code and upload the result into a server that can understand and run it. In consequence, hosting that will support HipHop be limited.

We have some questions before hand that will get answered pretty soon. How does HipHop compare with running PHP with APC enabled? Since Facebook contributed a lot to APC, we are assuming that using HipHop should be an improvement. We also are very curious to see how it will fare with frameworks like Symfony and Zend Framework.

Here at ServerGrove, our core business is PHP hosting, and as you can imagine that we are very excited about this announcement. As we were one of the first companies to offer PHP 5.3 hosting, we will test HipHop to see what it offers for PHP hosting. Part of our mission is to squeeze every single CPU cycle to offer the best performance from our servers so our customers’ websites run as fast as possible. If HipHop is as good as it sounds, be sure that it will be added to our products offering, but not before making sure we can provide the top-level support that our customers deserve and get from us.

We look forward to hearing your predictions on HipHop. How will symfony and Zend Framework fit in the schema of things? How will this affect our workflow? If HipHop is as good as it sounds, what will be the ultimate hosting product to go with it? Check back soon, as our tests materialize we will post them here.

03

02 2010

Enhanced Access Control for Symfony Front Controllers

A problem I have often encountered when working with Symfony projects containing multiple applications is the maintenance of the non-production front controllers. These front controllers contain a default check of the client IP address and must be modified to allow requests from any system except localhost (127.0.0.1). The creator of the application is then left to “roll their own” access control in order to facilitate development while still restricting the world at large.

While this is not a problem for Symfony projects which contain a single application, maintenance of these non-production front controllers can quickly become bothersome as the number of applications in the project grows. Any time an allowed address is added or removed all these front controllers need updated manually.

Listing 1 contains a solution to this problem. The source of the front controllers to be restricted gets replaced with this code (with the proper application name, environment, and debug setting of course). It is assumed the same set of IP addresses will have access to all the front controllers which use this code.

Listing 1: web/frontend_dev.php

<?php

if (false !== ($hosts = @file(dirname(__FILE__).'/../config/hosts.allow')))
{
  $hosts = array_map('rtrim', $hosts);

  foreach ($hosts as $host)
  {
    if (substr(@$_SERVER['REMOTE_ADDR'], 0, strlen($host)) == $host)
    {
      require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');

      $configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true);
      sfContext::createInstance($configuration)->dispatch();

      exit(0);
    }
  }
}

header('HTTP/1.0 403');
echo '403 Forbidden';

As you can see, the list of allowed addresses is stored in the config/hosts.allow file. This file simply contains an IP address (or partial IP address) to be allowed on each line. A sample hosts.allow file can be found in listing 2.

Listing 2: config/hosts.allow

127.0.0.1
209.85.225.104
192.168.0.
69.147.11.

Problem solved. Now whenever a new IP address or set of addresses needs to be allowed access to your restricted front controllers they simply need added to the hosts.allow file.

It should be noted when matching IP address blocks: since the check uses a substring match on the client address the trailing “.” needs included in the hosts.allow file. Otherwise an allowed address of “69.147.11″ would match “69.147.111″, “69.147.112″, etc.

Happy coding!

01

02 2010

One month to go for symfony live 2010

Just one month to go for the 2nd symfony live conference! This year’s event will be in English even though the event will be held in Paris. Who said the French refuse to speak English in France? The event organizers have put together a great presentation lineup. This is a great opportunity to meet with symfony developers, learn more about symfony and most important to be part of the release of Symfony 2.

This is the second year we sponsor symfony live and we can’t wait! We are looking forward to meeting developers, clients and friends. If you are going to be there, look for us and say hi!

15

01 2010

Happy Holidays

18

12 2009

Introducing the symfony web development environment installer

When Symfony 1.3 & 1.4 were released, little attention was given to a new feature that had tremendous potential: the installer. By adding –installer=installFile.php is possible to execute custom PHP code when creating a new symfony project.

So when I came across this I had an idea that could save us all some time. Every time we want to try some thing quick, do a prototype, test a plugin or simply start a new application, we create a new symfony project. The common workflow once the project is created is to add a new “virtual” hostname to the hosts file so we can reach the project through the browser, then add a virtual host to the Apache configuration, so the “virtual” hostname points to the correct web directory of the project, etc… These steps are repetitive and consume a bit of time and quite frankly I’d love to automate this whole thing. For that I created the symfony Web Development Environment Installer (also known as project codename: Swedein).

The installer will ask you a series of questions: ie. IP address, hostname, location of Apache installation. It can also locate the Apache configuration by looking for it in common places. Then it goes ahead and adds a line to the hosts file, adds the virtual host block to Apache’s configuration and restarts Apache. In a matter of seconds you should be ready to go.

swedein

To run the installer, you have a couple of options:

a) Download the installer file, rename it to SymWebDevInstaller.php and run:

symfony generate:project myproject --installer=path/to/SymWebDevInstaller.php

b) If you have support for http URLs in your PHP you can simply run:

symfony generate:project myproject --installer=http://labs.servergrove.com/SymWebDevInstaller/SymWebDevInstaller.php

Note: There is a bug in the generate:project task that prevents URLs from being used with the –installer option. This should be fixed soon.

This is being tested in:

  • Windows XP with Zend Server CE
  • Mac OS X with Zend Server CE
  • CentOS Linux
  • Ubuntu Linux

In Mac OS and Linux, the script will need to have permissions to update the hosts file and the Apache configuration. Make sure your user has permissions or use sudo to execute the installer. Restarting Apache is supported on Linux only. Other OSes coming soon.

We are looking for help to include and test in other types of installations and to add other improvements the community might think about. You can either check out the github repository where we can receive patches or send it to us and we will update it. We look forward to your feedback.

17

12 2009

Add a link checker panel to the symfony web debug toolbar

During December, symfony is releasing a chapter a day of the advent calendar. The articles are about advanced topics. So far we have read about routing, productivity enhancement, sending emails, custom widget and validators, forms, and one topic is about extending the Web Debug Toolbar.

The Web Debug Toolbar is one of the best features of symfony. It provides extensive information about your application (configuration & performance). The article explains how to extend the toolbar by adding custom panels. The possibilities are endless! Immediately after reading the article, I started thinking on different uses. I thought that a link checker would be a great addition. The idea would be to get all the links in the page currently looking at and detect broken links. So I started hacking something together. Here is the result.

Because the panel needs to check all links on the page, rendering the page gets slowed down considerably. So it becomes annoying after a few reloads, so I decided to only enable it by passing a parameter to the URL. By passing ?check_links to any URL in your project, it will check the links in the content of the response.

linkchecker_list

The panel also displays the title in red if there are any broken links by setting the status of the panel as described in the article. By clicking on the title, you get a list of all the links and its status.

linkchecker_status

I will prepare a plugin to encapsulate this functionality and I will release it. If you have any other ideas, let us know!

To install it, edit your config/ProjectConfiguration.class.php file and add this method:

  public function initialize()
  {
    $this->dispatcher->connect('debug.web.load_panels', array(
        'sgWebDebugPanelLinkChecker',
        'listenToLoadDebugWebPanelEvent'
    ));
  }

Then, download the sgWebDebugPanelLinkChecker.php class and put it in lib/debug. After that, add ?check_links to your URL and check it out. I actually found a couple of broken links in our site upon testing.

The article was great describing how to hide the panel, change its status and set the title and content, get a URL parameter, all features used in this example.

To do: Check https links.

14

12 2009

ServerGrove sponsoring Zendcasts

We wanted to give a big thank you to Jon Lebensold for the great work he is doing with Zendcasts. He is really helping the Zend Framework community with some of the best Zend Framework webcasts out there and we are very excited to be sponsoring Zendcasts for our very first episode on the topic of Doctrine Relations and Data Fixtures. Exciting stuff baby!

Check it out at zendcasts.com

We are offering a special promotion of 10% off using the coupon code “zc” on any hosting product to celebrate this occasion.

09

12 2009