好吧,正好准备将工作环境转换到MAC上,不了解的东西比较多,那么就没办法了,只好自己一步步摸索。这篇文章权作笔记。另,当前的操作系统版本是OSX10.7.2的LION。

吐槽下,虽然MAC上的操作系统OSX是UNIX like的,不过我贴了个linux标签,反正都差不多啦。。。

Part 1: MacPorts

一步步来,首先需要解决的软件安装工具的问题,毕竟谁也不想php、cgi、mysql一串软件全部自己手动下源码编译吧。所以我们需要安装MacPorts这个软件,这个软件会很方便地提供软件的安装,就像debian、ubuntu的apt和centos的yum一样。

安装很简单,直接到官网上下编译好的安装包就可以了,只要你在使用的操作系统没有太超前于MacPorts工作小组就行了。否则的话只好自己下载源码编译安装了。

具体细节就不多说了,直接上官网看就行了:http://www.macports.org/。需要提一点的是,一般家用的OSX系统下载了官方的安装包也不能直接安装成功,因为MacPorts依赖于Apple的开发软件Xcode,所以需要先到AppleStore上下载并安装Xcode先。恩,就这样。

另,下文会提到的port load命令,我man了下port的手册,手册里是这么说的:Provides a shortcut to using launchctl to load a port's daemon (as installed in /Library/LaunchDaemons).
还有就是需要建一个文件夹,很多程序的启动脚本以后都放在一个地方:mkdir /etc/init.d/

Part 2: 安装PHP和spawn-fcgi

安装完MacPorts之后就比较顺利了,不过PHP还是个坎。关键就在纠结的5.2和5.3的问题,5.3肯定是不装的,那么就是5.2了,而5.2又不是MacPorts的官方标准包,所以安装的时候就多出了很多麻烦事情。另外一点是,MacPorts下的PHP安装没有单独的cgi安装,而是将cgi作为PHP安装的一个参数带了进来,这个比较囧,一开始没搞明白。

关于安装时候带参数的事情在MacPorts是比较重要的,否则当你安装完毕的时候发现自己需要的东西居然没有那就囧了,具体可以参考:http://guide.macports.org/#development.variants

port -v install php52 +debug +fastcgi +mysql5 +readline +sockets
port -v install spawn-fcgi

这里插一句,因为macport在安装软件的时候是没有进度条的,所以我们需要带上-v参数,来查看安装细节。否则有的安装慢的软件,你就不知道它在干嘛了。

安装完成后,到/opt/local/etc/php5下,cp php.ini-recommended php.ini
然后修改几个项:

error_reporting = E_ALL & ~E_NOTICE
display_errors = On
error_log = /Users/jonathan/logs/php5/error.log
date.timezone = Asia/Shanghai

手动创建/Users/jonathan/logs/php5/error.log日志

启动脚本放在/etc/init.d下,起名php5-cgi,写完后记得给于执行权限chmod +x ./php5-cgi,脚本内容:

[codesyntax lang="bash"]

#!/bin/bash

DAEMON=/opt/local/bin/spawn-fcgi
HOST=127.0.0.1
PORT=9000

PHP_FCGI_CHILDREN=2
PHP_CGI=/opt/local/bin/php-cgi
PHP_CGI_NAME=php5-cgi

case "$1" in
  start)
        echo -n "Spawning PHP_CGI: "
        $DAEMON -C $PHP_FCGI_CHILDREN -a $HOST -p $PORT -f $PHP_CGI
        echo "$PHP_CGI_NAME."
        ;;
  stop)
        echo -n "Stopping PHP_CGI: "
        killall php-cgi
        echo "$PHP_CGI_NAME."
        ;;
  restart)
        echo -n "Restarting PHP_CGI: "
        killall php-cgi
        sleep 1
        $DAEMON -C $PHP_FCGI_CHILDREN -a $HOST -p $PORT -f $PHP_CGI
        echo "$PHP_CGI_NAME."
        ;;
  *)
        echo -n "Usage: $PHP_CGI_NAME {start|stop|restart}" >&2
        exit 1
        ;;
esac

exit 0

[/codesyntax]

Part3: 安装Nginx

首先执行安装命令:

port -v install nginx +status +ssl +flv

到/opt/local/etc/nginx下,执行命令:

cp nginx.conf.example nginx.conf
mkdir sites-enabled

接下去需要配置nginx的配置文件,并写一个nginx的启动脚本。配置文件我们这么改:

[codesyntax lang="bash"]

#user  nobody;
worker_processes  1;

error_log  /Users/jonathan/logs/nginx/error.log;
#error_log  /Users/jonathan/logs/nginx/notice.log notice;
#error_log  /Users/jonathan/logs/nginx/info.log   info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /Users/jonathan/logs/nginx/access.log;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;

    gzip  on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    include /opt/local/etc/nginx/conf.d/*.conf;
    include /opt/local/etc/nginx/sites-enabled/*;
}

[/codesyntax]

接着创建日志文件:

/Users/jonathan/logs/nginx/error.log
/Users/jonathan/logs/nginx/access.log

然后在sites-enabled文件夹里创建default这个配置文件:

[codesyntax lang="bash"]

server {

    listen   80; ## listen for ipv4
    listen   [::]:80 default ipv6only=on; ## listen for ipv6

    server_name  localhost;

    access_log  /Users/jonathan/logs/nginx/localhost.access.log;

    location / {
        root  /Users/jonathan/prog/www;
        index index.php index.html index.htm;
    }

    location /doc {
        root      /usr/share;
        autoindex on;
        allow     127.0.0.1;
        deny      all;
    }

    location /images {
        root   /usr/share;
        autoindex on;
    }

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /Users/jonathan/prog/www$fastcgi_script_name;
        include fastcgi_params;
    }

}

[/codesyntax]

最后创建localhost的日志:

/Users/jonathan/logs/nginx/localhost.access.log

启动脚本放在/etc/init.d下,起名nginx,写完后记得给于执行权限chmod +x ./nginx,脚本内容:

[codesyntax lang="bash"]

#!/bin/bash

DAEMON=/opt/local/sbin/nginx
NAME=nginx
DESC=nginx

case "$1" in
  start)
        echo -n "Starting $DESC: "
        $DAEMON
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        $DAEMON -s stop
        echo "$NAME."
        ;;
  restart)
        echo -n "Restarting $DESC: "
        $DAEMON -s stop
        sleep 1
        $DAEMON
        echo "$NAME."
        ;;
  test)
        echo -n "Testing $DESC: "
        $DAEMON -t
        echo "$NAME."
        ;;
  *)
        echo "Usage: $NAME {start|stop|restart|test}" >&2
        exit 1
        ;;
esac

exit 0

[/codesyntax]

Part4: 安装MySQL

执行安装命令:

port -v load mysql5-server

这个命令应该瞬间就完成了,因为在装PHP的时候mysql就一起装好了,虽然我不知道为什么。。。
这时候虽然mysql是装好了,但是数据库没有初始化完成,所以先要初始化:

/opt/local/lib/mysql5/bin/mysql_install_db

mysql的daemon在:/opt/local/lib/mysql5/bin/mysqld_safe &
官方的mysql启动脚本在:/opt/local/share/mysql5/mysql/mysql.server
官方的mysql的配置文件在:/opt/local/share/mysql5/mysql/my-*.cnf

接下来轮到我们干活了,先把配置文件放到制定地点:

cp /opt/local/share/mysql5/mysql/my-innodb-heavy-4G.cnf /opt/local/etc/mysql5/my.cnf

当然要修改点东西,添加项全部添加在[mysqld]下:
bind-address = 127.0.0.1
去掉log、和log_warnings前面的注释。

由于mysql的启动和配置比较复杂,这里不太方便将mysql默认的一系列配置文件导向到我们指定的文件,这里我们使用变通的方法来解决,首先创建文件夹/Users/jonathan/logs/mysql,然后制作软链接将mysql默认的日志文件链接到这个文件夹里。
安装完成的mysql的默认日志文件夹在:/opt/local/var/db/mysql5

ln -s /opt/local/var/db/mysql5/Jonathans-MacBook-Pro-slow.log /Users/jonathan/logs/mysql/slow.log
ln -s /opt/local/var/db/mysql5/Jonathans-MacBook-Pro.local.err /Users/jonathan/logs/mysql/error.log
ln -s /opt/local/var/db/mysql5/Jonathans-MacBook-Pro.log /Users/jonathan/logs/mysql/mysql.log

配置文件之后是启动脚本,官方的脚本已经够好了,我们只需要把它放到指定地点:

cp  /opt/local/share/mysql5/mysql/mysql.server /etc/init.d/mysql

恩,这样mysql的配置和启动就没问题了。可能这个时候你会发现直接执行mysql5命令,系统报错说命令未找到。这是因为系统的PATH配置有问题导致的。修复的方法很简单,在/etc/profile里添加这样一句就可以了:

PATH=/opt/local/bin:/opt/local/sbin:/opt/local/lib/mysql5/bin:$PATH

熟悉linux开发的朋友会发现一个地方很奇怪,一般来说mysql的可执行文件应该叫mysql,但是通过MacPorts安装的mysql的可执行文件名字叫mysql5,这就很囧了。我们可以通过制作软链接的方法来解决这个问题。

cd /opt/local/bin
ln -s mysql5 mysql

最后一步是关于安全的,通过MacPorts安装完mysql后官方还提供了一个脚本叫mysql_secure_installation5,执行这个脚本,mysql的安全会被全面检查,并协助你修改不安全的地方。

至于mysql的远程访问这里顺便提下,第一是要把my.cnf里的bind-address改成127.0.0.1,第二就是要在mysql中创建一个任何ip都可以访问的用户名,最后记得flush privileges。

至此mysql的安装就完成了,不得不说MacPorts的mysql安装实在是不怎么样,我写了那么多就是弥补官方安装包没做好的事情,囧。

Part5: 安装Memcached

执行安装命令:

port -v install memcached

会有一个依赖包的安装,不过很快就会装完了,很简单的。

我们需要做的是创建一个启动脚本,/etc/init.d/memcached:

[codesyntax lang="bash"]

#!/bin/bash

DAEMON=/opt/local/bin/memcached
NAME=memcached
DESC=memcached

USER=nobody
HOST=127.0.0.1
PORT=11211
MEM=32
LOG=/Users/jonathan/logs/memcached/info.log

case "$1" in
  start)
        echo -n "Startring $DESC: "
        $DAEMON -m $MEM -p $PORT -l $HOST -u $USER -d -vv >> $LOG 2>&1
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        killall $NAME
        echo "$NAME."
        ;;
  restart)
        echo -n "Restarting $DESC: "
        killall $NAME
        sleep 1
        $DAEMON -m $MEM -p $PORT -l $HOST -u $USER -d -vv >> $LOG 2>&1
        echo "$NAME."
        ;;
  *)
        echo "Usage: $NAME {start|stop|restart}" >&2
        exit 1
        ;;
esac

exit 0

[/codesyntax]

记得赋予可执行权限,最后不要忘记创建日志文件:

chmod +x /etc/init.d/memcached
touch /Users/jonathan/logs/memcached/info.log

Part6: 安装MongoDB

执行安装命令:

port -v install mongodb

这个会比较久,耐心等待。

安装完毕,那么工作开始,创建配置文件:

mkdir /opt/local/etc/mongodb
touch /opt/local/etc/mongodb/mongo.cnf

内容如下:

[codesyntax lang="bash"]

# Store data path
dbpath = /opt/local/var/db/mongodb/

# Bind address
bind_ip = 127.0.0.1

# Running as daemon
fork = true

# Take log
logpath = /Users/jonathan/logs/mongodb/info.log
logappend = true

[/codesyntax]

创建日志文件:

mkdir /Users/jonathan/logs/mongodb
touch /Users/jonathan/logs/mongodb/info.log

创建启动脚本,内容如下:

touch /etc/init.d/mongodb
chmod +x /etc/init.d/mongodb

[codesyntax lang="bash"]

#!/bin/bash

DAEMON=/opt/local/bin/mongod
NAME=mongodb
DESC=mongodb

PORT=27017
CONFILE=/opt/local/etc/mongodb/mongo.cnf
PIDPATH=/opt/local/var/db/mongodb
PIDFILE=$PIDPATH/mongod.lock

start_mongo() {
    $DAEMON --port $PORT --pidfilepath $PIDPATH --config $CONFILE  --auth run
}

stop_mongo() {
    if [ ! -f "$PIDFILE" ]
    then
        echo "MongoDb is not running!"
        return 1
    fi
    pid=`cat $PIDFILE`
    kill -15 $pid
    rm $PIDFILE
}

case "$1" in
  start)
        echo -n "Starting $DESC: "
        start_mongo
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        stop_mongo
        echo "$NAME."
        ;;
  restart)
        echo -n "Restarting $DESC: "
        stop_mongo
        sleep 1
        start_mongo
        echo "$NAME."
        ;;
  *)
        echo "Usage: $NAME {start|stop|restart}" >&2
        exit 1
        ;;
esac

exit 0

[/codesyntax]

安装完成。

Part7: 安装剩下的PHP扩展

现在我们面对着一个非常麻烦的问题,因为我们安装的PHP的版本是5.2,而不是MacPorts官方默认的5.3,这导致了其余的官方PHP扩展我们都不能用了。因为其余的PHP扩展在安装的时候会检查依赖包,然后发现依赖的php5包没有装,而装了和php5包冲突的php52包,所以安装就没办法执行下去了。这里我们只能手动来下载源码编译安装我们需要的PHP扩展了。

我们一个个来,首先是memcache。
因为memcache的安装依赖一个包名叫libmemcached,所以我们先装它,port install libmemcached。
接下来去http://pecl.php.net/package/memcache下载最新的稳定版本2.2.6,下载完成后解压,进入到文件夹里,依次执行以下命令:

phpize
./configure
make
make install

安装完成的扩展包会放在/opt/local/lib/php/extensions/debug-non-zts-20060613/下。
接下来我们要编辑下/opt/local/etc/php5/php.ini,把extension_dir这个参数改成上面的文件夹,让PHP能找到系列编译安装完成的扩展so文件。

接下来我们需要让PHP知道我们添加了这个memcache扩展,一般来说是需要改php.ini文件。但是我不想这么做,否则以后东西越来越多,php.ini文件也会越来越乱。那么怎么办呢?我们可以使用外部ini文件路径来创建自己的子ini配置文件,打开phpinfo()页面,查看一栏叫“Scan this dir for additional .ini files”的,这个文件夹就是子ini配置文件夹。但是你会发现这个文件夹和我们放php.ini的文件夹不是同一个文件夹,这样非常不方便我们记忆和修改,所以这里要做一个文件夹的软链接。

mkdir /opt/local/etc/php5/conf.d
ln -sF /opt/local/var/db/php5 /opt/local/etc/php5/conf.d

最后我们需要在conf.d文件夹里创建我们的配置文件memcache.ini,并在里面添加一句extension=memcache.so,就完成了。
重启php的cgi,现在应该能在phpinfo里查看到memcache的信息了。
启动完成后我们还需要添加一句话来调整配置:

[memcache]
memcache.hash_strategy="consistent"

这个配置会保证memcache的hash算法是一致性算法。

apc。
方法和memcache一致,只是下载的地方改下:http://pecl.php.net/package/APC,下载版本选用最新的稳定版本3.1.9。
在apc.ini文件中添加配置:

[apc]
apc.enabled=0
apc.enable_cli=0

因为在开发环境我们并不需要开启缓存机制,如果有需要做压力测试的时候只要把这两个或者一个值打开就行了。

xdebug。
下载:http://pecl.php.net/package/xdebug,版本2.1.2。
同样,添加配置:

[xdebug]
xdebug.profiler_enable=Off
xdebug.profiler_output_dir=/Users/jonathan/logs/xdebug
xdebug.profiler_output_name=cachegrind.out.%s.%u.%p
xdebug.auto_trace=Off
xdebug.trace_output_dir=/Users/jonathan/logs/xdebug
xdebug.trace_output_name=trace.%c

不要忘记位xdebug创建日志文件夹:

touch /Users/jonathan/logs/xdebug

mongo。
下载:http://pecl.php.net/package/mongo,版本1.2.6。
添加配置:

[mongo]
mongo.native_long=true