Configure your web developer environment under OS X
This is how I manage my web developer environnement on mac OS X. I use textmate as text editor, but you’re free to use anyone that take your precedence.
My environnement is inspired by the cinderella project, but I customize it… I use extensively the Terminal.app, so, if you’re not comfortable with, you must learn how to use it, or you should consider another integrated solution (but if you’re a good web developer, you use it a lot, isn’t it ?)
Prerequisites
Most of the tools used in my environnement are installed using homebrew, the missing package manager for OS X. To use it, you first need to install the Apple Developer Tools Xcode. Just download and install it from the Mac AppStore.
Next, you need to install the package manager homebrew. To prevent any incursion to the system, and to maintain an homogeneous dev environnement, we chroot all of them in the ~/Developer directory :
$ git clone https://github.com/mxcl/homebrew.git ~/Developer
Then, you must indicates to your system that your binaries are located in this directory. First, create a file named ~/Developer/profile :
$ mate ~/Developer/profile
And fill it with the following content :
# Homebrew in ~/Developer
PATH="$HOME/Developer/bin:$HOME/Developer/sbin:$PATH"; export PATH
MANPATH="$HOME/Developer/share/man:$MANPATH"; export MANPATH
OK, now everything is ready for. Just close an relaunch your terminal window to open a new session and initialize you $PATH environnement variable. To check if everything sounds good, type the following command, you should see a similar output :
$ brew --version
0.8
Install UNIX tools
First, we need to install GIT. It is now shipped with Xcode, but the given version isn’t the most recent …
$ brew install git
Now, install the rest of the UNIX tools
$ brew install bash-completion gettext pidof
To use bash-completion, you need to init it in your profile, so re-open your profile (~/Developer/profile) and add the following at the end of the file :
# Bash_completion
if [ -f `brew --prefix`/etc/bash_completion ]; then
. `brew --prefix`/etc/bash_completion
fi
You can install the homebrew part for bash-completion :
$ ln -s "~/Developer/Library/Contributions/brew_bash_completion.sh" "~/Developer/etc/bash_completion.d"
I also use ImageMagick for image manipulation in a CLI way
$ brew install imagemagick
Install the whole environnement
The system is ready, let’s go !
Install a custom Python
You can use python for many things, included for the web using some greate frameworks like Django.
$ brew install python
$ ~/Developer/share/python/easy_install pip
Databases
I use several types of databases, SQL and NOSQL :
$ brew install mysql postgresql memcached mongodb
Init MySQL :
$ unset TMPDIR
$ mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=~/Developer/var/mysql --tmpdir=/tmp
Init PostgreSQL :
$ initdb ~/Developer/var/postgre
Create the LaunchAgents. The daemons are launched when your session starts, and you can use the launchctl to manipulate them :
$ mkdir -p ~/Library/LaunchAgents
$ cp ~/Developer/Cellar/mysql/5.5.15/com.mysql.mysqld.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/com.mysql.mysqld.plist
$ cp ~/Developer/Cellar/postgresql/9.0.4/org.postgresql.postgres.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/org.postgresql.postgres.plist
$ cp ~/Developer/Cellar/memcached/1.4.9/com.danga.memcached.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/com.danga.memcached.plist
$ cp ~/Developer/Cellar/mongodb/2.0.1-x86_64/org.mongodb.mongod.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/org.mongodb.mongod.plist
Use Nginx as webserver
In this lightweight environnement, I doesn’t want to use the heavy apache webserver. I’ve decided to use nginx, because of its small memory use, and its fast responding. It is also particularly easy tose with ruby/rails app, and fastcgi app (like PHP).
So, first, install it : $ brew install nginx $ cp ~/Developer/Cellar/nginx/1.0.9/org.nginx.nginx.plist ~/Library/LaunchAgents/ $ launchctl load -w ~/Library/LaunchAgents/org.nginx.nginx.plist
Next, configure the webserver :
$ mate ~/Developer/etc/nginx/nginx.conf
Here is the content of my config file :
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type text/plain;
server_tokens off;
sendfile on;
tcp_nopush on;
keepalive_timeout 10;
gzip on;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/css text/javascript application/json application/x-javascript text/xml application/xml application/xml+rss;
server {
listen 8080;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
}
include sites-enabled/*.conf;
}
Next, create the folders that will contains the virtalhosts config files.
$ mkdir ~/Developer/etc/nginx/sites-{available,enabled}
Create a file for a virtualhost. For the root directory, I personally place all my virtualhosts codebases in the ~/Sites subfolder.
$ mate ~/Developer/etc/nginx/sites-available/ressources.dev.conf
And fill the file with the following :
server {
listen 8080;
server_name ressources.dev;
root /Users/mad/Sites/ressources.dev;
error_log /Users/mad/Sites/ressources.dev/logs/error.log;
autoindex on;
location / {
index index.html index.php;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9001;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
In this one, I preset the virtualhost to use the PHP. More info on this later ;) …
Then, link your virtualhost to activate it ; and tell nginx to reload the config :
$ ln -s ~/Developer/etc/nginx/sites-available/ressources.dev.conf ~/Developer/etc/nginx/sites-enabled/
$ nginx -s reload
Finally, set your virtualhost in your hosts file :
$ mate /etc/hosts
Add the line :
127.0.0.1 ressources.dev
Your site is available at http://ressources.dev:8080.
Now, repeat the steps for all the virtualhosts you need.
Install PHP-FPM
PHP-FPM is a new, better, and faster fastcgi PHP server. Unfortunately, it is not available in homebrew. But luckily, it is available on the adamv hombrew-alt repository :
$ brew install https://raw.github.com/adamv/homebrew-alt/master/duplicates/php.rb --with-mysql --with-pgsql --with-fpm
Now, create a LaunchAgent plist file for the PHP-FPM :
$ mate ~/Library/LaunchAgents/net.php.php-fpm.plist
With the following :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>net.php.php-fpm</string>
<key>LaunchOnlyOnce</key>
<true/>
<key>NetworkState</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/Users/mad/Developer/sbin/php-fpm</string>
<string>--fpm-config</string>
<string>/Users/mad/Developer/etc/php-fpm.conf</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceDescription</key>
<string>PHP FastCGI Process Manager</string>
<key>StandardErrorPath</key>
<string>/var/log/system.log</string>
</dict>
</plist>
And configure the php-fpm server by modifying the file
$ mate ~/Developer/etc/php-fpm.conf
with the settings :
pid = /Users/mad/Developer/var/run/php-fpm.pid
error_log = /Users/mad/Developer/var/log/php-fpm.log
daemonize = yes
listen = 127.0.0.1:9001
user = nobody
group = nobody
pm = dynamic
pm.max_children = 10
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500
And launch the php-fpm server :
$ launchctl load -w ~/Library/LaunchAgents/net.php.php-fpm.plist
Great ! You’ve got a webserver running, a php-fpm server backend, and everythings work together… Now, you must use xdebug :
$ brew install xdebug
$ mate ~/Developer/etc/php.ini
Add these lines in the dynamic extensions part :
zend_extension=/Users/mad/Developer/Cellar/xdebug/2.1.2/xdebug.so
xdebug.remote_enable=1
xdebug.remote_host=localhost
xdebug.remote_port=9000
xdebug.remote_autostart=1
And reload nginx :
$ nginx -s reload
You can use MacGDBp and an XDebug browser extension toggler for safari, firefox or chrome for a user-friendly XDebug interface.
Customize your Ruby environnement
For a better flexibility in my ruby env, I use rbenv to manage the versions. Simply install it :
$ brew install rbenv ruby-build
Modify your profile
$ mate ~/Developer/profile
by adding
# rbenv
if [[ -x $HOME/Developer/bin/rbenv ]]; then
eval "$(rbenv init -)"
fi
And install at least one version of ruby in rbenv
$ rbenv install 1.9.3-p0
$ rbenv global 1.9.3-p0
$ rbenv rehash
Use JavaScript Server-side
You can use javascript server-side for many tools. I use many scripts, like uglifyJS to minimize my JS scripts. For the use of javascript server-side, I use NodeJS :
$ brew install node
And set your paths in your profile
$ mate ~/Developer/profile
with :
# NodeJS
if [[ -d $HOME/Developer/lib/node ]]; then
export NODE_PATH="$HOME/Developer/lib/node:$HOME/Developer/lib/node_modules"
fi
Install npm, the nodejs packages manager
$ curl http://npmjs.org/install.sh | sh
And, if you want to install uglifyJS, simply type :
$ npm --global install uglify-js
Keep your installation clean
OK, now, you’ve got a good environnement. Keep in mind to update it regularly. To do this :
$ brew update && brew upgrade
$ npm --global update
Be careful, for the new versions of the deamonized processes, to update correctly the LauchDaemon plists files.
If you want to manage more simply the daemons, you can use lunchy, a ruby utility to do this. Install it with :
$ sudo gem install lunchy