Thursday, April 16, 2009

Configuring Apache for Agile Development of PHP Applications

This is the first in a series of articles detailing how to setup an agile PHP development environment. Each article should be fairly contained, although I would still recommend you read the summary to get the recommendations for how to approach these articles to benefit the most.

Implementation Time(1-5 hours depending on OS, apache skill, and sites)
The implementation time is most dependant on your own skill with apache, followed closely by the configuration changes required by your sites. Finally, if you can't easily setup the method you want to serve PHP(MPM changes, mod_php, suexec, fastcgi, etc.) locally easily this could bork the time table I provided significantly.

Process
The process we will be going by will be simple.

  • Get a LAMP stack running.
  • Configure httpd.conf
  • Configure virtual host for each project
  • Configure /etc/hosts(or similar OS specific file) for seperate projects
  • Install sites to ~/workspace folder
  • (Optional) Configure tcp_wrappers or windows firewall to allow external access
I will additionally be covering how to setup multiple SSL certificates locally if you need this capability. Let's get started!

Get a LAMP stack running
I am not going to go into details about this, because it is beyond the scope of the article really. This topic is huge and can be very complicated. If you are running linux, please visit your distributions home page for instructions. Here are some for Gentoo(using mpm-itk):
  • I have the following use flags in /etc/make.conf "mysql apache2 php5" as well as APACHE2_MPMS="itk"
  • edit /etc/portage/package.use I recommend the following use configurations.
  • dev-lang/php doc mysql mysqli xml simplexml hash curl pdo ctype json tokenizer
  • www-servers/apache doc rewrite itk
  • dev-db/mysql doc
  • emerge -av php mysql apache (this is if you don't want to do an apache split e-build)
If you are running windows, you can get WAMP here. That one installer should give you a working local web server.

If you are running OSX and don't mind, send me information to post here about the basics for installation on of setting this up.

Regardless of your OS, I recommend enabling mod_rewrite, mod_setenv, and using the mpm-itk MPM if at all possible(keep in mind this can be a real pain on some distros, its easy with Gentoo =P ). mpm-itk will make apache run as your user so that you dont have to chmod 0777 all the files that you want apache to edit. It is not the best solution for this effect, but the easiest to setup for some.

Configure httpd.conf
So now you have LAMP/WAMP running and are ready to get to my tips for PHP developers. I recommend setting up your httpd.conf to be as minimal as possible. Here is what I recommend:

ServerRoot [path to server root]

#Load Modules ( all of your LoadModule statements here )

ServerName [local hostname of computer]
User apache
Group apache

DirectoryIndex index.php

Include /etc/apache2/modules.d/*.conf
Include /etc/apache2/vhosts.d/*.conf

That's it! The load modules section should be pretty large but this is a really simple configuration. Gentoo does most of this for you. The modules.d folder should contain all of the specific configuration changes you require of each specific module. I use nearly the defaults here. The vhost.d folder we will be going into more detail pretty shortly here. Note that you don't see a default host here.

Configure virtual host for each project
We will be configuring each project as a virtual host. That will allow us to run multiple projects locally without problems. We will also need to configure a default virtual host. This can be a custom page you have put together listing all of your projects or a specific site you want displayed by default. That I will leave to your preference. We will make a series of files in vhost.d numbered and named by project. Here is an example 01_vhost_site1.localhost.conf:


ServerName site1.localhost
ServerAlias site1.localhost
AssignUserID [your user] [your user's group]

ErrorLog /home/[your user]/workspace/logs/site1.localhost-error
DocumentRoot /home/clintv/workspace/site1/

Options -Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all



There are some changes you might need to make. The AssignUserID is line is only if you enabled mpm-itk. If you went the fastcgi route, or some other route you will need to add the appropriate line to set the sites user instead. You will need to make sure to create the ~/workspace/logs folder for all of your logs from your sites. You may also want to change the "Allow from all" to "Allow from 127.0.0.1" if you want to prevent external access to the site. I do this with my firewall/tcp_wrappers, personally. I don't like directory browsing, but if you do remove the - in "-Indexes". You will be placing your site at ~/workspace/[project]. This plays well with Eclipse for those that like to use it. If you need subdomains, I recommend keeping them in the projects conf file and duplicating the above for the seperate path to the subdomain.

If you need SSL for a project, then make an additional config file that is for serving the site in SSL. Here is 01_vhost_ssl_site1.localhost.conf:

Listen 443

ServerName site1.localhost
ServerAlias site1.localhost
AssignUserID [your user] [your user's group]

SSLEngine On
SSLCertificateFile /etc/apache2/ssl/site1.crt
SSLCertificateKeyFile /etc/apache2/ssl/site1.key

ErrorLog /home/[your user]/workspace/logs/site1.localhost-error
DocumentRoot /home/clintv/workspace/site1/

Options -Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all



There is not much extra here. We have changed the port to 443, setup the SSL certificate and key locations, and are logging to the same log file. You may need to specify a specific local IP(see below) for each SSL site if you are dealing with multiple. You may also prefer to log to a seperate file.

Configure /etc/hosts(or similar OS specific file) for seperate projects
With all of our new virtual host, we need to let our OS know where to find the sites. The file we will be editing is /etc/hosts. On windows, this file is located in windows/system32/drivers/etc/hosts. Here is an example with multiple projects:

127.0.0.1 localhost.localdomain localhost [your hostname]
127.0.0.1 site1.localhost site2.localhost store.site2.localhost site3.localhost
127.0.1.1 site4.localhost
::1 localhost

This is simple enough. I have basically listed off each [project].localhost to resolve to 127.0.0.1. site4 actually requires a seperate SSL ip address, so I have assigned it 127.0.1.1. Also, site2 has a subdomain of store. This would allow me to have a seperate path and emulate the real server conditions of a subdomain.

Install sites to ~/workspace folder
This is fairly easy. Unpack your project to ~/workspace/[project]. This is where you would check out your source code repository. I will explain the way I setup this directory in the article about setting up an Agile PHP build system. As a heads up, I usually put the actual website in a folder named src.

(Optional) Configure tcp_wrappers or windows firewall to allow external access
If you want someone to be able to access the site externally, you will need to configure you firewall so that they can connect. If your in linux, your magic phrase is tcp_wrappers. Here is the lines to enable http and https for /etc/hosts.allow:

HTTP: all
HTTPS: all

If your in windows, then it is the windows firewall. You may also need to configure port forwarding from your router if your hosting across the internet. A good dynamic dns service goes a long way as well. I like to use no-ip because they have a linux client that will update your ip address if it changes. If you do this, I would recommend creating a special vhost conf file for that hostname your sharing. Keep in mind you will only be able to host SSL for 1 site this way unless you have multiple internet ip addresses.

Summary
This article has armed you with the tools to configure apache in a logical way for multiple project development. Feel free to make your own changes, and if you have great personal tips, post them as comments for the rest of the visitors please. =)

Creating an Agile Development Environment for PHP

This is the first in a series of articles I am writing to teach you how to develop in an agile PHP environment. I will be presenting all of this information in person at the Houston PHP meet-up in April of 2009.

Over the course of the last couple of years, I have drifted around various development environments looking for the right one for me. After finding a great setup, and using it for long enough to see some of it's kinks, I have decided to document my journey for the rest of you. Now I must forwarn you, this is not the definitive end all document for how to setup your php work environment. I recommend that you try everything here, but only keep what really helps your performance the most. Many motivational speakers do recommend working outside your comfort zone occasionally, there is a reason for this. However, different developers operate more efficiently in different conditions. In fact, lets start with the conditions that are typical of my projects, so that you can start to get the insight into the knowledge I am attempting to fire at you here.

The most important thing to acknowledge is that I typically do not have a team of developers. However, I would like to make the point that an entire team of developers should actually be using something close to this anyways. I have also had nearly full control of the deployment environment. I have pretty much run the most bleeding edge stable version of PHP available for the last 2 years. What does that mean to the developers? Well, it means that you don't have to cater to some of the more obscene hoops that some folks do. In fact, if I didn't have control over the deployment server, it was probably a cPanel server. Again though, the setup I am using should deploy to pretty much any setup you would be using PHP.

There are also a couple of things that I consider non-typical skill sets. I want to disclose those right now so as to give warning to those who don't have those skills when they wonder why I use a particular setup. I work efficiently on the command line. I prefer using the keyboard to the mouse for the majority of everything. I am proficient in linux, as well as the system's administration of LAMP. I know how to operate gentoo fairly well, or at least I would like to think I do. If you aren't a command line or only operate well in windows, don't be afraid. I will try to have windows instructions of everything that I am doing currently now as well, so that you can learn from this as well. Ultimately though, I hope that you take the time to learn how to operate linux effectively for yourself. You will be happy with the results.

The final thing I would like to cover before getting into the nitty gritty details of this is how to implement these articles. If you attempt to read the brunt of these articles and implement them all at once, you are destined for trouble. Unless you are in downtime, I would recommend being steady about your implementation. Some of the articles can be implemented in less than a few hours without further reprecussions(mostly the sys admin articles like apache configuration, etc.). Some of the articles, however, have a large learning curve and will almost always come with efficiency hit(like using VIM+Yakuake as an IDE). I will do my best to give an estimation of the amount of work required to implement each article.

So without further purposement, here are links to all of the articles:

Thursday, April 2, 2009

Giving back to the community

So I finally did it, I made a blog.  I think it is finally time for me to blog about my ups and downs in the world of a php developer.  I hope to give back to some people out there some of the help I have received over the last decade of my life in forums, chat rooms and blogs.  So let's begin with my current ordeal.

I have been working on collegiateaccess.net for quite a while now.  None of the application source code is documented though.  They have 20+ year software vet reviewing the code that is having trouble with understanding it.  I have been tasked with documenting the entire project, along with the framework that was erected for it.  I have chosen phpDocumentor for the task.

Ironically enough, I have run into some documentation problems with the tool.  I have not been able to find a definitive resource on how to build the INI configuration file it uses.  Somehow, I must have skimmed over the documentation stating that this tool was to be run from the browser as well.  I learned rather quickly that once you fetch the PEAR package(I actually emerged it through Gentoo's marvelous portage), you must copy the phpDocumentor to a location on the web server you will be running it from.  I am actually running 3 folders in my project(trunk, documentation, phpdoc).  The phpdoc folder is copied from /usr/share/php/data/PhpDocumentor/ on my Gentoo system.  So from the project root:

cp -R /usr/share/php/data/PhpDocumentor/* phpdoc/

On my testing bed, the project root is the web root for that domain, so the application is accessed 'domain/trunk/', the documentation 'domain/documentation/', and phpDocumentor at 'domain/phpdoc/'.  The next step that had to be taken to get phpDocumentor to produce some documentation was to build the ini file.  So make a file [project].ini in your phpdoc folder.  This is where I ran into a real dilemna, what to put in the ini file.  It is actually not that bad.

[ParseData]
title = [the title of this documentation]
hidden = false
defaultcategoryname = Documentation
defaultpackagename = [project]
target = /home/[user]/workspace/[project]/documentation/
filename = /home/[user]/workspace/[project]/trunk/index.php,/home/[user]/workspace/[project]/trunk/app/collegiate.php
directory = /home/[user]/workspace/[project]/trunk/includes/,/home/[user]/workspace/[project]/trunk/app/controllers/,/home/[user]/workspace/[project]/trunk/app/models
sourcecode = on
output = HTML:frames:DOM/default,PDF:default:default,CHM:default:default

Let's go through this.  The hidden=false line prevents hidden files from being displayed.  defaultcategoryname is not really used all that much to my limited knowledge.  defaultpackagename is the package that all files not being notated with a @package [name] tag will be set to.  target is the location where the documentation will be placed.  filename is a comma seperated list of files to parse.  directory is a comma seperated list of directories to parse.  sourcecode=on means that the source code will be visible in the documentation.  This option requires that php has the 'tokenizer' enabled at compile time.  Gentoo users should have php compiled with the 'tokenizer' use flag.  output is a comma seperated list of modes with which to generate the documentation.  This one seemed to be the prettiest HTML version to me, and I wanted the PDF and CHM.  Please note that the paths I have included may not be correct for your setup and the [user] and [project] strings should be replaced to correctly reflect your path.  Also, I am not sure why, but I had to use absolute paths.  Relative paths were causing lots of trouble for me.

Once you have your ini file, you just need to do 3 things before you can generate your documentation.  Set the working directory at the bottom of the web interface(domain/phpdoc) to the absolute path of your project.  Go to config and type the absolute path to your project(or the folder you placed the ini file in).  Click change to change your configuration directory.  Go back to the config section once the page refreshes and select your ini file from the drop-down.  Click go to generate your documentation.

I hope this helps someone, because I had more trouble with this than I feel like I should have had.