如何在 OSX 上架設 Nginx+MariaDB+PHP (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

    1
    
    ruby -e $(curl -fsSL https://raw.github.com/mxcl/homebrew/go)
    
  4. 輸入下面的指令讓其他程式知道 Xcode 的位置。

    1
    
    sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
    
  5. 之後,「按此」下載最新版本的 X11 並且安裝。

  6. 之後建立 X11 的符號鏈接(軟鏈接)。

    1
    
    sudo ln -s /opt/X11 /usr/X11
    
  7. 之後使用下面的指令查看透過 Homebrew 安裝的套件。

    1
    
    brew list
    
  8. 之後輸入下面指令查看當前系統變數。

    1
    
    $PATH
    
  9. 打開「.bash_profile」並修改系統變數。

    1
    
    vim ~/.bash_profile
    

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

    1
    
    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。

1
   sudo postfix start

安裝 dnsmasq 設定 DNS

  1. 透過 Homebrew 安裝 dnsmasq ,以加速網路存取速度。

    1
    
    brew install dnsmasq
    
  2. 複製和編輯 dnsmasq.conf 。

    1
    2
    3
    
    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 內的數值。

    1
    2
    3
    
    resolv-file=/etc/resolv.dnsmasq.conf
    address=/.ld/127.0.0.1
    listen-address=127.0.0.1
    
  4. 建立並編輯 DNS 解析文件。

    1
    
    sudo vim /etc/resolv.dnsmasq.conf
    
  5. 在「resolv.dnsmasq.conf」文件內貼上以下內容。

    # Cloudflare DNS IPv6 DNS:
    nameserver 2606:4700:4700::1111
    nameserver 2606:4700:4700::1001
    # Google DNS IPv6 DNS:
    nameserver 2001:4860:4860::8888
    nameserver 2001:4860:4860::8844
    # OpenDNS IPv6 DNS:
    nameserver 2620:0:ccd::2
    nameserver 2620:0:ccc::2
    # Cloudflare IPv4 DNS:
    nameserver 1.1.1.1
    nameserver 1.0.0.1
    # Google IPv4 DNS:
    nameserver 8.8.8.8
    nameserver 8.8.4.4
    # OpenDNS IPv4 DNS:
    nameserver 208.67.222.222
    nameserver 208.67.220.220
    
  6. 設定開機自動執行 dnsmasq 。

    1
    2
    
    sudo cp $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons
    sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
    
  7. 設定你的 Hostname 。

    1
    
    sudo scutil --set HostName foolegg
    
  8. 打開「系統設定」,在「網絡」內分別選擇「Wi-fi」和「Ethernet」,在「進階」內設定「127.0.0.1」為DNS伺服器。

安裝 Nginx

  1. 輸入下面指令關閉自動啟用 Apache 。

    1
    
    sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist
    
  2. 之後透過 Homebrew 安裝 Nginx 。

    1
    
    brew install nginx
    
  3. 安裝完成後,複製和備份 nginx.conf 。

    1
    
    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 資料夾和其它必要的目錄。

    1
    2
    3
    4
    
    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 。

    1
    
    brew install mariadb --use-llvm --env=std
    
  2. 取消 TMPDIR 設定。

    1
    
    unset TMPDIR
    
  3. 初始化 MySQL 數據庫。請將 5.5.30 更改為你當前使用的版本編號。

    1
    2
    
    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 。

    1
    2
    3
    4
    5
    6
    7
    8
    
    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 。

    1
    
    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 檔案。

    1
    
    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 的符號鏈接(軟鏈接)。

1
   sudo ln -s  $(brew --prefix josegonzalez/php/php53)/var/log/php-fpm.log /usr/local/var/log/php-fpm.log

開機啟用服務

  1. 設定 Nginx 的啟用服務。

    1
    2
    
    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」。

    1
    
    sudo vim /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
    
  3. 在「homebrew.mxcl.nginx.plist」內刪除以下內容。

    <key>KeepAlive</key>
    <true></true>
    <key>UserName</key>
    <string>[YourUserName]</string>
    
  4. 開啟 Nginx 。

    launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
    
  5. 為軟件建立資料夾。

    1
    
    mkdir -p ~/Library/LaunchAgents
    
  6. 設定 MariaDB 的啟用服務。

    1
    2
    
    cp $(brew --prefix mariadb)/homebrew.mxcl.mariadb.plist ~/Library/LaunchAgents/
    launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
    
  7. 設定 PHP 的啟用服務。

    1
    2
    
    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 的設定。

    1
    
    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 。

    1
    
    vim /usr/share/nginx/www/public_html/index.php
    
  2. 輸入並儲存以下內容。

    1
    
    <?php phpinfo(); ?>
    
  3. 從新啟動 Nginx 。

    1
    
    sudo nginx -s reload
    
  4. 打開瀏覽器,輸入「http://localhost/index.php」查看是否成功運行PHP。

啟動或停止 MNMP

  1. 在桌面或其他位置建立 Shell Script「mnmp.sh」。

    1
    
    vim mnmp.sh
    
  2. 在 Shell Script「mnmp.sh」內加入以下內容,然後儲存檔案。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    
    #!/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」加入可執行權限。

    1
    
    chmod 700 mnmp.sh
    
  4. 使用以下指令啟動 MNMP 。

    1
    
    ./mnmp.sh start
    
  5. 使用以下指令停止 MNMP 。

    1
    
    ./mnmp.sh stop
    

PHP 檔案存取錯誤

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

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

> \[error\] #0: \* kevent() reported that connect() fa iled (: 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 。

```bash
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. 在文件內加入以下內容。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <plist version="1.0">
        <dict>
            <key>KeepAlive</key>
            <true></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></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 內加入以下內容。

    1
    2
    3
    4
    5
    6
    7
    
    # 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
    
Made in Hong Kong