Showing posts tagged nginx

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