MNMP

MNMP

本教學示範如何在 OSX 上架設 Nginx/MariaDB/PHP (MNMP – MacOSX + Nginx + MariaDB + PHP) 伺服器。當中,MacOSX是作業系統;Nginx是網頁伺服器;MariaDB是資料庫管理系統;PHP是指令碼語言。

本教學大部份內容參考自Brian Gilbert編寫的文章「nginx / MariaDB / PHP / Aegir on Mac OS X with optional Drush 5 (works on Mountain Lion!)」。

注意︰筆者使用vim作為編輯器。如果你使用其他編輯器,請自行更改有關指令內容。

安裝 Xcode 、 Homebrew 和 X11

  1. 打開「Mac App Store」下載並安裝「Xcode」。
  2. 打開「Xcode」,按下同意並接受Xcode的使用條款。
  3. 打開「終端機(Terminal)」,輸入下面的指令並且安裝Homebrew
    ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
  4. 輸入下面的指令讓其他程式知道Xcode的位置。
    sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
  5. 之後,「按此」下載最新版本的X11並且安裝。
  6. 之後建立X11的符號鏈接(軟鏈接)。
    sudo ln -s /opt/X11 /usr/X11
  7. 之後使用下面的指令查看透過Homebrew安裝的套件。
    brew list
  8. 之後輸入下面指令查看當前系統變數。
    $PATH
  9. 打開「.bash_profile」並修改系統變數。
    vim ~/.bash_profile

    將「/usr/local/bin」放在「/usr/local/sbin」之前。例如︰

    export PATH=~/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin:/usr/local/git/bin:/opt/local/bin
  10. 接着,請參考文章「[教學] 在 OSX 10.8 上設定 Postfix 郵件傳送代理 (MTA)」設定Postfix。
  11. 啟用Postfix。
    sudo postfix start

安裝 dnsmasq 設定 DNS

  1. 透過Homebrew安裝dnsmasq,以加速網路存取速度。
    brew install dnsmasq
  2. 複製和編輯dnsmasq.conf。
    mkdir /usr/local/etc
    cp $(brew --prefix dnsmasq)/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf
    vim /usr/local/etc/dnsmasq.conf
  3. 更改dnsmasq.conf內的數值。
    resolv-file=/etc/resolv.dnsmasq.conf
    address=/.ld/127.0.0.1
    listen-address=127.0.0.1
  4. 建立並編輯DNS解析文件。
    sudo vim /etc/resolv.dnsmasq.conf
  5. 在「resolv.dnsmasq.conf」文件內貼上以下內容。
    # Google DNS IPv6:
    nameserver 2001:4860:4860::8888
    nameserver 2001:4860:4860::8844
    # OpenDNS IPv6:
    nameserver 2620:0:ccd::2
    nameserver 2620:0:ccc::2
    # Google DNS:
    nameserver 8.8.8.8
    nameserver 8.8.4.4
    # OpenDNS:
    nameserver 208.67.222.222
    nameserver 208.67.220.220
  6. 設定開機自動執行dnsmasq。
    sudo cp $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons
    sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
  7. 設定你的Hostname。
    sudo scutil --set HostName foolegg
  8. 打開「系統設定」,在「網絡」內分別選擇「Wi-fi」和「Ethernet」,在「進階」內設定「127.0.0.1」為DNS伺服器。

安裝 Nginx

  1. 輸入下面指令關閉自動啟用Apache。
    sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist
  2. 之後透過Homebrew安裝Nginx。
    brew install nginx
  3. 安裝完成後,複製和備份nginx.conf。
    cp /usr/local/etc/nginx/nginx.conf /usr/local/etc/nginx/nginx.conf.bak
  4. 打開nginx.conf,刪除所有內容,使用下面的內容取代。
    # Nginx web server main configuration file nginx.conf
    #
    user www-data staff;
    worker_processes  4;
    worker_rlimit_nofile  8192;
    
    error_log   /usr/local/var/log/nginx/error.log;
    #pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include        mime.types;
    
        default_type           application/octet-stream;
        sendfile               on;
        keepalive_timeout      10;
        tcp_nodelay            on;
        gzip                   on;
        client_max_body_size   100M;
        #access_log    /usr/local/var/log/nginx/access.log  main;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        ## FastCGI.
        include /usr/local/etc/nginx/fastcgi.conf;
    
        ## For the filefield_nginx_progress module to work. From the
        ## README. Reserve 1MB under the name 'uploads' to track uploads.
        #upload_progress uploads 1m;
    
        #include /etc/nginx/conf.d/*.conf;
        #include /usr/local/etc/nginx/aegir.conf;
    
        server {
            listen          80;
            server_name     localhost;
            server_tokens   off; 
            #access_log     /usr/local/var/log/nginx/access.log	main;
            root            /usr/share/nginx/www/public_html;
    
            location / {
                root        /usr/share/nginx/www/public_html;
                index       index.html index.htm;
    
                ##### Use this if you're going to install wordpress #####
                #if (-f $request_filename/index.html) {
                #    rewrite (.*) $1/index.html break;
                #}
                #if (-f $request_filename/index.php) {
                #    rewrite (.*) $1/index.php;
                #}
                #if (-f $request_filename) {
                #    rewrite (.*) /index.php;
                #}
                #if (!-e $request_filename) {
                #    rewrite ^.+?(/wp-.*) $1 last;
                #    rewrite ^.+?(/.*\.php)$ $1 last;
                #    rewrite ^ /index.php last;
                #}
                #rewrite /wp-admin$ $scheme://$host$uri/ permanent;
                ##### End #####
            }
    
            error_page  500 502 503 504  /50x.html;
            location = /50x.html {
                root /usr/share/nginx/www/public_html;
            }
    
            location ~ \.php$ {
                fastcgi_pass    127.0.0.1:9000;
                fastcgi_index   index.php;
                fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include         fastcgi_params;
            }
        }
    }
  5. 之後建立Nginx的log資料夾和其它必要的目錄。
    sudo mkdir -p /usr/local/var/log/nginx/
    touch /usr/local/var/log/nginx/error.log
    touch /usr/local/var/log/nginx/access.log
    sudo mkdir -p /usr/share/nginx/www/public_html

安裝 MariaDB

  1. 透過Homebrew安裝MariaDB。
    brew install mariadb --use-llvm --env=std
  2. 取消TMPDIR設定。
    unset TMPDIR
  3. 初始化MySQL數據庫。請將5.5.30更改為你當前使用的版本編號。
    cd /usr/local/Cellar/mariadb/5.5.30/scripts
    mysql_install_db --user=`whoami` --basedir="$(brew --prefix mariadb)" --datadir=/usr/local/var/mysql --tmpdir=/tmp

    系統會提示錯誤,請忽略有關錯誤。下面的教學設定會更正錯誤。

安裝 PHP

  1. 雖然OSX上已經安裝了PHP,但是我們不會使用Apple的PHP。
  2. 輸入下面的指令安裝PHP。
    brew tap josegonzalez/homebrew-php
    brew tap homebrew/dupes
    brew install php53 --with-mysql --with-fpm --with-imap
    brew install php53-xhprof
    brew install php53-xdebug
    brew install php53-uploadprogress
    brew install php53-memcached
    brew install php53-imagick
  3. 打開並修改php.ini。
    vim /usr/local/etc/php/5.3/php.ini
  4. 搜索
    extension=php_zip.dll

    在下面加上以下內容,請更改版本編號。

    extension="/usr/local/Cellar/php53-xhprof/0.9.2/xhprof.so"
    extension="/usr/local/Cellar/php53-uploadprogress/1.0.3.1/uploadprogress.so"
    extension="/usr/local/Cellar/php53-memcached/2.1.0/memcached.so"
    extension="/usr/local/Cellar/php55-imagick/3.1.0RC2/imagick.so"
    zend_extension="/usr/local/Cellar/php53-xdebug/2.2.1/xdebug.so"
  5. 到「PHP手冊」尋找你身處地區的時區。修改php.ini內的「date.timezone」變數的數值。
    date.timezone = Asia/Hong_Kong
  6. 尋找以下3個變數的數值。如果找不到,請在檔案的最尾部份加上3個變數和數值。
    magic_quotes_gpc = Off
    magic_quotes_runtime = Off
    magic_quotes_sybase = Off
  7. 修改記憶體和上傳限制的數值。如果變量前出現分號「;」,請將之刪除。
    memory_limit = 256M
    post_max_size = 100M
    upload_max_filesize = 100M
  8. 打開並修改php-fpm.conf檔案。
    vim /usr/local/etc/php/5.3/php-fpm.conf
  9. 搜索
    pid = run/php-fpm.pid

    在下面加上

    pid = /usr/local/var/run/php-fpm.pid

    之後刪除下面4行變數和數值前的分號「;」。

    pm.start_servers = 3
    pm.min_spare_servers = 3
    pm.max_spare_servers = 5
    pm.max_requests = 500
  10. 按照下面修改「error_log」的數值。
    error_log = /usr/local/var/log/php-fpm.log
  11. 之後建立log的符號鏈接(軟鏈接)。
    sudo ln -s  $(brew --prefix josegonzalez/php/php53)/var/log/php-fpm.log /usr/local/var/log/php-fpm.log

開機啟用服務

  1. 設定Nginx的啟用服務。
    sudo cp $(brew --prefix nginx)/homebrew.mxcl.nginx.plist /Library/LaunchDaemons/
    sudo chown root:wheel /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
  2. 打開並修改「homebrew.mxcl.nginx.plist」。
    sudo vim /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
  3. 在「homebrew.mxcl.nginx.plist」內刪除以下內容。
    <key>KeepAlive</key>
    <true/>
    <key>UserName</key>
    <string>[YourUserName]</string>
  4. 開啟Nginx。
    launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
  5. 為軟件建立資料夾。
    mkdir -p ~/Library/LaunchAgents
  6. 設定MariaDB的啟用服務。
    cp $(brew --prefix mariadb)/homebrew.mxcl.mariadb.plist ~/Library/LaunchAgents/
    launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
  7. 設定PHP的啟用服務。
    cp $(brew --prefix josegonzalez/php/php53)/homebrew-php.josegonzalez.php53.plist ~/Library/LaunchAgents/
    launchctl load -w ~/Library/LaunchAgents/homebrew-php.josegonzalez.php53.plist
  8. 完成MariaDB的設定。
    sudo $(brew --prefix mariadb)/bin/mysql_secure_installation
  9. 為MySQL設定密碼。
    Enter current password for root (enter for none): [Enter]
    Set root password? [Y/n] y
    New password: [password]
    Re-enter new password: [password]
    Remove anonymous users? [Y/n] y
    Disallow root login remotely? [Y/n] y
    Remove test database and access to it? [Y/n] y
    Reload privilege tables now? [Y/n] y

測試PHP

  1. 建立並修改index.php。
    vim /usr/share/nginx/www/public_html/index.php
  2. 輸入並儲存以下內容。
    <?php phpinfo(); ?>
  3. 從新啟動Nginx。
    sudo nginx -s reload
  4. 打開瀏覽器,輸入「http://localhost/index.php」查看是否成功運行PHP。

啟動或停止MNMP

  1. 在桌面或其他位置建立Shell Script「mnmp.sh」。
    vim mnmp.sh
  2. 在Shell Script「mnmp.sh」內加入以下內容,然後儲存檔案。
    #!/bin/bash
    
    case "$1" in
    	start)
    
    		# Start MariaDB
    		echo -e "Starting mariadb..."
    		launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
    
    		# Start PHP
    		echo -e "Starting php..."
    		launchctl load -w ~/Library/LaunchAgents/homebrew-php.josegonzalez.php53.plist
    
    		# Start Nginx
    		echo -e "Starting nginx..."
    		sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
    
    		;;
    
    	stop)
    
    		# Stop MariaDB
    		echo -e "Stopping mariadb..."
    		launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
    
    		# Stop PHP
    		echo -e "Stopping php..."
    		launchctl unload -w ~/Library/LaunchAgents/homebrew-php.josegonzalez.php53.plist
    
    		# Stop Nginx
    		echo -e "Stopping nginx..."
    		sudo launchctl unload -w /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
    
    		;;
    esac
    
    exit 0
  3. 為Shell Script「mnmp.sh」加入可執行權限。
    chmod 700 mnmp.sh
  4. 使用以下指令啟動MNMP。
    ./mnmp.sh start
  5. 使用以下指令停止MNMP。
    ./mnmp.sh stop

PHP檔案存取錯誤

有部份讀者反映在存取PHP檔案時出現錯誤。大家可以打開檔案「/usr/local/var/log/nginx/error.log」查看錯誤的原因。

如果出現下面的原因,可能是因為php-fpm的問題。

[error] <NUMBER>#0: *<NUMBER> kevent() reported that connect() fa iled (<NUMBER>: Connection refused) while connecting to upstream, client: 127.0.0. 1, server: localhost, request: “GET /index.php HTTP/1.1”, upstream: “fastcgi ://127.0.0.1:9000”, host: “127.0.0.1”

大家可以使用「netstat -anp tcp | grep 9000」或者「lsof -i tcp:9000」查看佔用Port 9000的進程,並且將其終止。之後使用下面指令開啟php-fpm。

sudo /usr/local/sbin/php-fpm --fpm-config /usr/local/etc/php/5.3/php-fpm.conf

請再次測試是否成功存取php。如果成功,請依照下面設定自動啟動php-fpm。

設定自動啟動php-fpm

  1. 建立文件「~/Library/LaunchAgents/org.php-fpm.plist」。
  2. 在文件內加入以下內容。

    <?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>org.php-fpm</string>
     <key>ProgramArguments</key>
     <array>
     <string>/usr/local/sbin/php-fpm</string>
     <string>–fpm-config</string>
     <string>/usr/local/etc/php/5.3/php-fpm.conf</string>
     </array>
     <key>RunAtLoad</key>
     <true/>
     <key>UserName</key>
     <string>root</string>
     <key>WorkingDirectory</key>
     <string>/usr/local/var</string>
     <key>StandardErrorPath</key>
     <string>/usr/local/var/log/php-fpm.log</string>
    </dict>
    </plist>

  3. 在mnmp.sh內加入以下內容。

    # Start PHP-FPM
    echo -e "Starting PHP-FPM..."
    sudo launchctl load -w ~/Library/LaunchAgents/org.php-fpm.plist
    # Stop MariaDB
    echo -e "Stopping mariadb..."
    sudo launchctl unload -w ~/Library/LaunchAgents/org.php-fpm.plist