歡迎您光臨本站 註冊首頁

把Apache換成Nginx筆記

←手機掃碼閱讀     火星人 @ 2014-03-04 , reply:0

把Apache換成Nginx筆記

其實想把Apache換成Nginx已經很多年了,只是一直懶得弄,也可能是因為上了年紀的關係,有點得過且過的意思。當然更主要的原因是沒有壓力,目前我的所有應用在Apache下都跑得挺好,對Apache的配置也比較熟悉。但是Nginx 10倍的性能優勢始終在那裡,這是一個擋不住的誘惑。

上周與令狐和幫主小聚的時候順手在手機的Ubuntu里裝了個Nginx,但是Ubuntu 9.04帶的那個版本實在太老了,也就沒有再弄。後來因為換手機把那個Ubuntu搞掉了,還沒重裝,這兩天就在工作機的Ubuntu 12.04上來裝了個配置一下。後來還正式部署到了一台Debian伺服器上。順便做點筆記。
安裝

在Ubuntu 12.04下是簡單。

apt-get install nginx php5-cgi php5-cli php5-fpm php-doc

不過在Debian 6下就麻煩一些,因為apt里沒有php5-fpm,只能源碼安裝,或者使用這個源:

#在 sources.list 里加入以下源
sudo echo "deb http://php53.dotdeb.org stable all" >> /etc/apt/sources.list
#或者:deb http://packages.dotdeb.org stable all
#如有必要還可以再加上:deb-src http://packages.dotdeb.org stable all
#加入key
wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | sudo apt-key add -
rm dotdeb.gpg
sudo apt-get update
sudo apt-get install php5-fpm

初步配置

首先關閉Apapche的自啟動,可以用 sysv-rc-conf 來配置。

然後配置php-fpm,主要修改這幾個文件:

/etc/php5/fpm/php.ini
/etc/php5/fpm/php-fpm.conf
/etc/php5/fpm/pool.d/www.conf

第一個為與php有關的配置,這裡要有這一句:

cgi.fix_pathinfo = 0;

原因見nginx默認配置文件中的註釋說明。

第二個為fpm有關的配置,通常沒什麼要改的。

最後一個為與web有關的配置,可以在這裡修改fpm的監聽埠號什麼的。
基本的nginx配置

主要的配置文件是這些:

/etc/nginx/nginx.conf
/etc/nginx/conf.d/*.conf
/etc/nginx/sites-enabled/*

基本上不需要修改nginx.conf,所有跟全站http相關的配置都可以放在conf.d/*.conf里,各虛擬主機的配置則放在sites-enabled/*里即可。

參考全站公共配置內容:

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

charset utf-8;

這裡有一點需要注意的是:charset設置並不能保證輸出一定是utf-8。對於靜態文件來說一般沒問題,但是對於動態內容來說(比如來自PHP或Python WSGI),即使返回內容的確是用utf-8編碼,但是沒有在HTTP響應頭裡指定編碼方式的話,nginx會默認為 ISO-8859-1 ,即使這裡指定了utf-8也沒用,結果就是導致在FireFox等瀏覽里器顯示亂碼(部分瀏覽器會識別網頁中的meta,不一定按照HTTP響應頭的指定編碼方式)。

解決方案有兩個:一是治標的辦法——在nginx配置里加入一個ISO-8859-1到utf-8的charset_map(內容為空即可,當然這樣的話碰到真正的ISO-8859-1內容時會亂碼)。另一個當然是治本的——在動態內容里增加HTTP響應頭內容,指定編碼方式。

參考虛擬主機配置:

server {
        listen   80; ## listen for ipv4; this line is default and implied
        server_name yoursite.com www.yoursite.com;

        root /home/username/www;
        index index.html index.htm index.php;

     error_log   /var/log/nginx/yoursite.error.log warn;
     access_log  /var/log/nginx/yoursite.access.log main;

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        location / {
                # This is cool because no php is touched for static content.
                # include the "?$args" part so non-default permalinks doesn't break when using query string
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  /home/username/www$fastcgi_script_name;
                include        fastcgi_params;
                fastcgi_intercept_errors on;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }

        location ~ /\.ht {
                deny all;
        }
}

此配置根據nginx官方的wordpress配置修改而來。注意其中的SCRIPT_FILENAME一行,此行缺少會導致PHP頁面顯示空白,但HTTP響應為沒有錯誤的200,此行錯誤則會導致html顯示正常,但php顯示404找不到。

配置完成後啟動nginx和php5-fpm。

sudo /etc/init.d/php5-fpm start
sudo /etc/init.d/nginx start

停止的方式類似:

sudo /etc/init.d/php5-fpm stop
sudo /etc/init.d/nginx stop

SSL配置

這個配置倒很簡單,跟Apache基本一樣。證書生成的部分就不說了,都是用openssl搞的。不過nginx默認是用.crt/.key文件,apache還可以用.pem文件,實際上可以手工把.pem文件拆成.crt/.key。

基本配置如下:

server {
    listen   443; ## listen for ipv4

    server_name yoursite.com;

    ssl  on;
    ssl_certificate  /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key  /etc/nginx/ssl/nginx.key;

    ssl_session_timeout  5m;

    ssl_protocols  SSLv3 TLSv1;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
    ssl_prefer_server_ciphers   on;

     error_log   /var/log/nginx/yoursite.error.log warn;
     access_log  /var/log/nginx/yoursite.access.log main;

# 其它配置與 http 相同
# 如
    location /webalizer {
        root /home/username/www;
        index index.html
        autoindex off;
    }

}

另外要注意的是:php5-fpm那邊是不知道nginx這邊是否使用https的,所以用 $_SERVER['HTTPS'] 將取得空串,需要這樣設置一下:

location ~ \.php$ {
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  /home/username/www$fastcgi_script_name;
# 注意這句
                fastcgi_param HTTPS on;

                include        fastcgi_params;
                fastcgi_intercept_errors on;
        }

gevent-WSGI配置

以web.py為例。首先需要修改web.py的代碼以使用gevent-WSGI(雖然這只是個參考實現,但性能還是很不錯的)。

if __name__ == "__main__":
    from gevent import socket
    from gevent import monkey
    monkey.patch_all()
    from gevent.wsgi import WSGIServer
    import pwd

    sys.stdout = sys.stderr

    SOCK = "/var/www/sockets/webpy.sock"
    pe = pwd.getpwnam('www-data')
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    try:
        os.remove(SOCK)
    except OSError:
        pass
    sock.bind(SOCK)
    os.chown(SOCK, pe.pw_uid, pe.pw_gid)
    os.chmod(SOCK, 0770)
    sock.listen(256)
    WSGIServer(sock, app.wsgifunc()).serve_forever()

改完即可啟動監聽相應的socket。

python /home/username/webpy/start-gevent.py 2>> /var/log/nginx/webpy.log &

其次是修改nginx,將相應的請求轉發到web.py+gevent-WSGI的監聽socket。

參考配置:

location /webpy {
        try_files $uri @webpy;
    }

    location @webpy {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_pass http://unix:/var/www/sockets/webpy.sock;
    }

    location /webpy/static {
        root /var/www;
        autoindex off;
    }

搞定收工。

原文http://www.zzt123.com/html/2012/0822/1345635371.html
《解決方案》

不錯的文章,頂,
《解決方案》

做個標記:lol

[火星人 ] 把Apache換成Nginx筆記已經有769次圍觀

http://coctec.com/docs/service/show-post-11478.html