Wednesday, June 2, 2010

Multiple Zend Framewok applications on Ubuntu

This article is only slightly Zendy, and a bit more about how to configure Ubuntu so that you can work on multiple websites at once for local development. It does include a few tips on how I think the default index.php file should be modified if you are using Zend Framework libraries for multiple sites, so even if you are using a different development environment you may still find that part useful. This does not cover setting up sites that the rest of the world can see, after they are ready I assume you will FTP them to another server or something. Since I am having to do this now in order to develop and test code for this blog, I figured now would be a good time to write about it.

There are a few files that you will need to worry about:
/ect/hosts (list of hostnames)
/etc/network/interfaces (for setting up multiple network IP addresses, reboot after changing)
/etc/apache2/httpd.conf (includes site-specific httpd.conf files to configure Virtual Hosts)

In /etc/hosts, you will first set the loopback IP addresses to point to your server. Then pick some IP's like 192.168.X.Y to use for your sites. Anything on 192.168 is using your private network, which is what you want here. There were a few "default" lines at the end of /etc/hosts; you can leave them in, they won't hurt anything. Here is an example of what /etc/hosts should look like:
127.0.0.1       your_computer_name
127.0.1.1 your_computer_name

192.168.13.1 mooneleaf
192.168.13.2 zendreflections

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
In /etc/network/interfaces, you can now use tap to create a map to each IP address you have configured. Here is an example using the IP addresses selected above:
auto lo
iface lo inet loopback

auto tap0
iface tap0 inet manual
up ifconfig tap0 192.168.13.1 up
down ifconfig tap0 down
tunctl_user root

auto tap1
iface tap1 inet manual
up ifconfig tap1 192.168.13.2 up
down ifconfig tap1 down
tunctl_user root
In /etc/apache2/httpd.conf, you will just include in your site-specific httpd.conf files that will do the actual configuration of your Virtual Hosts. Here is an example:
Include /data/mooneleaf/httpd.conf
Include /data/zendreflections/httpd.conf
So let's say that you are starting a brand new Zend Framework project, as I am. In that case, you can use the Zend Framework command line tool to create your initial project files like this:
$ /data/lib/ZendFramework-10.2/bin/zf.sh create project zendreflections
Next create your project-specific httpd.conf file. I like to keep my Zend Framework libraries in a separate location so they can be referenced by all my various Zend Framework projects. Since I use subversion to manage my code, it also makes sense to keep the Zend libraries separate from my repository. I can keep multiple versions and then just reference the specific one I am using in my index.php, which makes it easy to keep up with which version is being used at any given time. Here is an example of httpd.conf for my zendreflections project:
<VirtualHost>
ServerName 127.0.0.1
DocumentRoot /data/zendreflections/public

<Directory>
AllowOverride All
Options All
</directory>

php_value magic_quotes_gcc off
php_value register_globals off

</VirtualHost>
You'll need a couple of modifications to the index.php file to include your Zend libraries. Since your Zend libraries may be in a different location for different application environments, add a switch statement to specify their location. I also like to use the ZendX libraries, so I'll include the path to "extras" as well. Here is what I think is a better format for the top half of index.php:
// Define the base path
defined('BASE_PATH')
|| define('BASE_PATH', realpath(dirname(dirname(__FILE__))));

// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', BASE_PATH . '/application');

// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));

// Define Zend Framework version
defined('ZF_VERSION')
|| define('ZF_VERSION', '1.10.2');

// Keep switch statement updated when adding environments
switch (APPLICATION_ENV) {
case "development":
$zendDir = '/data/lib/Zend/ZendFramework-' . ZF_VERSION;
break;
}

// Ensure application, library, and ZF libraries are on include path
set_include_path(implode(PATH_SEPARATOR, array(
APPLICATION_PATH,
BASE_PATH . '/library',
$zendDir . '/library',
$zendDir . '/extras/library',
get_include_path(),
)));
Actually, I would recommend to put all this into a separate application.php file and just include it from your index.php. That way, if you want to set up another entry point to your application later (for web services, for example) all your setup code can be reused.

You will probably need to reboot for your changes to /etc/network/interfaces to take effect, but once you do you this and type "zendreflections" (or whatever label you chose for your IP address) into the URL, you should see the reassuring "Welcome to the Zend Framework" message and you can finally start to develop your awesome web application. Happy coding!

No comments:

Post a Comment