In the past1, I’ve been a big fan of running a virtualized web server locally instead of intalling PHP and Apache (or Nginx) directly on my development machine. I think I just changed my mind.
A little over a month ago, I read Elliot Jay Stocks’ article abou the stuff he missed on vacation. One of those things was the release of Anvil. Anvil is really just a nice looking front-end for Pow. Pow is a local rack web server built on node.js. It adds some cool stuff to /etc/resolvr
to handle DNS for development domains and then you just symlink a directory into ~/.pow
to get a server at a domain like .dev
.
For some reason I’ve never really been a fan of MAMP. I think the “zero-config” thing stuck with me when I saw Pow though. So I started looking around2 to see if I could use Pow with PHP apps.
It turns out to be possible. There’s a gem called rack-legacy which is exactly for this purpose. Unfortunately rack-legacy uses the CGI version of PHP which doesn’t come in Mountain Lion. So you have to install PHP from source, which requires you to install mcrypt from source as well.
- Install mcrypt from source.
- Download the PHP source over at the PHP Downloads page.
cd
into the PHP source directory and configure it./configure --with-cgi --enable-mbstring --with-curl --with-xmlrpc --with-mcrypt=/usr
make
andmake install
PHP.
So, now that we have PHP set up, install Pow, Rack, and all the other dependancies.
brew install node sqlite
gem install rack rack-legacy rack-rewrite
curl get.pow.cx | sh
I think the only dependancy for pow is node, which I used homebrew to install. I also installed sqlite because it’s easier to use locoally than MySQL. And Laravel makes it simple to switch over to a SQLite database.
It’s finally time to set up our Laravel app. Rack apps need a config.ru
file in the root which is just a Ruby script that configures the server for this particular app. Put the following config.ru
in Laravel’s public
folder and point Pow at the same folder.
require 'rack'
require 'rack-legacy'
require 'rack-rewrite'
use Rack::Rewrite do
send_file %r{([^?]+)}, Dir.getwd + '$1', :if => Proc.new { |env|
path = File.expand_path(Dir.getwd + env['PATH_INFO'])
File.file?(path)
}
rewrite %r{(.*)?}, 'index.php$1'
end
use Rack::Legacy::Php, Dir.getwd
run Rack::File.new Dir.getwd
That’s it.
Resources
There were kind of two main resources that I used to fully understand what was going on here and how to set this up. If you’re going to be a PHP developer and use Ruby tools, get used to seeing PHP as “Legacy Development” I guess.
-
I’ve written a few articles about setting up a VM in VirtualBox for PHP development locally. Including the original, part 2, the one about nginx, and the video. ↩
-
I even considered writing my own “zero-configuration” web server that would work with PHP for a minute. ↩
PHP5.4 comes with a server built in. Zero config.
Try Vagrant (http://vagrantup.com/). I use this with multiple developers. I got one box with advanced setup including fulltext search, APC caching, etc. Can fire up my develop project on any machine.
is there anything wrong with the Apache proxy forwarding method described on the Pow github wiki here?
https://github.com/37signals/pow/wiki/Running-Pow-with-Apache
FYI i do it and it seems to work, just wondering if you knew any pitfalls. This is the virtualhost catch-all for *.dev domains:
https://raw.github.com/gist/1058580/zzz_pow.conf
Whatever works. I tried that first and for some reason PHP wasn’t working, but props if it’s working for you.
I know this is an older post but still quite relevant…
It’s disappointing that the only real “solution” to a development environment is using Chef/Puppet/Berkshelf with Vagrant to provision a SECOND computer to run things on. Sure, it’s nice to have predictable “production”-like environments but we all know we can’t always reproduce our production environments exactly, especially if we don’t provision our production servers to start with.
For practical, average joe, time is of the essence-folks – we need some sort of (not necessarily zero-config) but at least something easier than having to manage apache / mysql / php, etc locally or on a virtual box.
I’m sure once everyone masters chef / puppet then someone will write a nice CLI to just generate boxes + chef / puppet all in one without a thought in the world…
So let’s think about the variables in play here…
Let’s narrow our thoughts strictly to web development for a moment.
We would need a way to define (on a per project basis) our dependencies for the project.
For instance, you’re tasked with a WordPress-based project so you know you’ll need at least, Apache2/HTTPD, MySQL / PosgreSQL, and PHP5.
So we type a command:
$ cd ~/Projects
$ automagic init my_project_name apache2 mysql5 php5
And it goes about it’s business placing dependencies in an automagic_modules folder with a npm / rubygems feel.
You then type:
$ cd my_project_name
$ automagic start
And you get an apache2 instance configured with mysql5 and php5.
I don’t even care if it has the /etc/resolv magic that Pow has.
I just want something minimally configurable that will do this stuff and run it from a simple folder.
I know this would be a huge undertaking but I think it would be awesome to tackle for the web dev community.
Ideally it would be cross-platform and the only “dependency” modules we would have to map out would be those requires for developing web applications. We could write some of them to start, and have the community contribute the rest.
It’s ambitious but if we used some sort of “homebrew” type logic or “rubygems” logic to manage dependencies we could swing this I think.
If anyone is interested in contributing, let me know and I’d be glad to dedicate some weeks to this.
-Josh
So, a lot of this exists already. Check out: https://puphpet.com/
The WordPress community, in particular, has been all about Vagrant lately. There are quite a few projects like this under way. There has even been some talk about including a Vagrantfile directly in the WordPress dev repo.