I’ve been a long time MAMP user, but I recently upgraded my laptop and decided to do a fresh install of everything, and a ground up re-configuration of all my dev environments (a fair bit of mucking about with PHP, Ruby, Java, Python and trying Go).

After a short while researching it became clear the best tool for the job would be Homebrew – it gives you much more control of the environment than MAMP, without the Macports heartache.

In this post I’ll run through using Homebrew on OSX Mountain Lion for a Mysql+PHP CGI setup – I’ll document adding a webserver to this stack in a later post, my immediate need is for a PHP CGI environment.

Setup Homebrew

Before you do any of this, go grab Xcode from the App Store. Hope you’re not on a 3G internet connection, it’s a 1.6GB install! Go grab a coffee while you wait. After that’s installed you’re also going to need to go to Xcode > Preferences and install the command-line tools, another 100+ MB install.

The Homebrew install from their own site is just:

ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"

Setup PHP

Homebrew uses the tap command to import more sources for install scripts. See what they did there? I use the homebrew-php project, seems awesome – loads of support, docs and info on the project page, all going to plan you’ll just need these two commands below.

brew tap josegonzalez/homebrew-php
brew tap homebrew/dupes

You can review all the options with the brew options php54 command, if you want mysql and CGI, use the command below that I used.

brew install --with-mysql --with-cgi php54

It’ll run through a bunch of downloading/compiling steps but the end result should be that you get the following test output:

/usr/local/bin/php-cgi --version
PHP 5.4.12 (cgi-fcgi) (built: Mar 19 2013 14:39:37)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

Setup MySQL

It’s super easy, watch.

brew install mysql

Then just follow the instructions that get blurted out during the Homebrew install of mysql.

Slight catch is, if your OSX is anything like mine you’ll need to run this first:

mkdir -p /usr/local/var/mysql
unset TMPDIR
mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp

I also got this warning:
WARNING: Found existing config file /usr/local/opt/mysql/my.cnf on the system. which you can safely fix with:

#backup existing
mv /usr/local/opt/mysql/my.cnf /usr/local/opt/mysql/my.cnf.old
#move new
mv /usr/local/opt/mysql/my-new.cnf /usr/local/opt/mysql/my.cnf

There’s also a lot of good advice for securing your mysql install blurted out during the install process, ignore it at your peril. Test your handiwork by checking you can access the mysql commandline prompt:

mysql -uroot
# or, with the password you set. You set one, right?
mysql -uroot -p

Other Notes

I noticed that the Homebrew installed PHP didn’t seem to support $_ENV in scripts, instead the $_SERVER array seems to be used – the Macports PHP with CGI support did seem to work with $_ENV. It might be a subtle version difference, I’m actually not sure, and decided not to spend time trying to figure it out. Just update scripts that depend on $_ENV, to use $_SERVER. If someone knows what’s behind this, please share.

So, that should be it, PHP with CGI support and MySQL installed and ready to rock. If I missed anything let me know.

I’m forever having to look up various types of obscure GQL syntax to use in the App Engine console. I thought I’d start a blog post where I note them down, for my own sake. I’ll update this as I go.

Look up entities by encoded key string

SELECT * FROM EntityName WHERE __key__ IS KEY('dkfjbILVUYFkfbaelIIUBkuafvKJ')

Look up child entities by encoded key string

SELECT * FROM EntityName WHERE ancestor IS KEY('dkfjbILVUYFkfbaelIIUBkuafvKJ')

More to come, if you find one I’m missing let me know

In this post I’ll run through the quick steps required to update your AWS Auto-Scaling group to use a new EC2 AMI. This post builds on the guide covered in my earlier post on setting up an Auto scaling group for an elastic load balancer, which in turn was built on the WordPress clustering guide. You could say this is part 3 in a rather long-running series.

There’s not much too this process thankfully.

Step 1: Create your new AMI

The easiest way I have found to do this is actually via the EC2 console. All I do is start a new instance on my current AMI, log into it and make any changes required (install/update packages etc) and then from the EC2 console, select the instance.

You don’t often need to log into the slave nodes, so if you need a refresher on how to do it, this command is all you should need:

ssh -i path/to/your/key.pem user@your-public-ip-of-the-node.compute-1.amazonaws.com

Continue Reading…

What if money were no object?

December 18, 2012 — 6 Comments

I saw this really thoughtful YouTube clip a while back, and wanted to record it here, so I can refer people to it in the future. If you haven’t seen it yet, take 3 minutes and watch it. It makes me feel very fortunate, I love writing software.

As you may know, we run our OrderPipe ecommerce dashboard on Google’s App Engine – I’m a big fan of the platform, but it has some traps for new (and old) players. A recent issue required us to bulk delete entities on App Engine, and for that it seemed the best tool for the job was the ‘Mapper’ part of Map Reduce. It was a good experience learning a) how it works and b) applying it, I thought I’d document a full Map Reduce example, because the worked examples I found were all based on an older version of the library.

Background

You might be interested to read a bit about why I had to use Map Reduce – it was my own fault. A subtle bug in a recent release caused an additional Account to be created under certain situations – it made it past our staging server, because that certain situation happened infrequently enough to not cause an issue, but once it got to production, where we have many thousands of orders arriving daily, we started seeing a lot of zombie accounts being created. My first thought was we were being attacked, but alas, it wasn’t an attack, just a bug! The nett result, we were left with 10′s of thousands of unwanted entities.

The Problem

In App Engine, the datastore is highly scalable, but it’s not relational, you can’t just run a simple query to delete all rows in a table with a particular created timestamp. There are simple tools to blindly delete all entities of a type, but not entities that meet a particular condition, and more importantly, not related entities that also meet a particular condition. That’s where Map Reduce comes in, basically we shard the entities and create multiple parallel workers to break the collection into smaller parts and process through them quickly. This seems like an inefficient approach until you consider scaling beyond a single database server, or even a single database cluster.
Continue Reading…