Cách thiết lập NGINX làm Proxy cho Apache

Cách đây cũng mấy ngày rồi mình có đăng một bài case study về việc tối ưu cho một website WordPress có hàng trăm user online cùng lúc với server chỉ có 2GB RAM và 1 CPU. Do có nhiều bạn yêu cầu nên ở bài này mình sẽ hướng dẫn chi tiết cách cài đặt một Webserver sử dụng Apache và có NGINX làm proxy để tải các dữ liệu tĩnh.

Tuy nhiên, ở bài này mình chỉ hướng dẫn cài đặt cho server chạy 1 website duy nhất, còn chạy nhiều website thì bạn có thể test rồi tự đúc kết.

Tổng quan về kỹ thuật

nginx apache proxy

Như các bạn cũng đã biết là Apache là một Open Source Webserver phổ biến nhất hiện nay bởi vì có rất nhiều software tuyệt vời hỗ trợ cho nó như cPanel, DirectAdmin,…điều mà NGINX chưa có. Số lượng người dùng cũng rất đông đảo và hầu như 90% shared host sử dụng Apache. Trong WordPress, nếu bạn sử dụng Apache thì cũng sẽ có lợi hơn vì toàn bộ các plugin có yêu cầu bạn sửa đổi file cấu hình của Webserver đều hoạt động rất tốt trên Apache, cụ thể hơn là các plugin đó yêu cầu bạn sửa file .htaccess.

Tuy nhiên nhược điểm của Apache là kém linh hoạt, xử lý hơi chậm và quan trọng nhất là chiếm khá nhiều bộ nhớ mỗi khi xử lý bất kỳ dữ liệu nào, dù nó là tĩnh hay động.

Và rồi, chúng ta đến với NGINX như một giải pháp thay thế cho Apache vì NGINX xử lý nhanh hơn, linh hoạt hơn (sử dụng trong nhiều mục đích khác nhau) và nhẹ hơn Apache rất nhiều. Cách cấu hình của NGINX cũng gọn gàng và đơn giản hơn.

Nhưng có một vấn đề là nếu bạn sử dụng NGINX như một Webserver chính để xử lý các dữ liệu PHP (như serie LEMP của mình) thì đôi lúc nó sẽ hoạt động không đúng như ý muốn, mà nói đơn giản hơn là nếu bạn dùng trong WordPress thì sẽ phải cần khả năng tự cấu hình rất nhiều, điều này không mấy dễ chịu cho newbie.

May mắn thay, bản thân NGINX rất đa nhiệm nên chúng ta có thể sử dụng nó đồng hành cùng với Apache mà không gây ảnh hưởng gì, thậm chí bạn còn tiết kiệm được nhiều tài nguyên hơn, website tải nhanh hơn nữa. Một kỹ thuật thông dụng nhất để sử dụng NGINX cùng với Apache là làm proxy trung gian để gửi dữ liệu đã xử lý thông qua Apache đến trình duyệt của người dùng. Nếu bạn nào đã và đang lập trình Ruby cho việc làm web thì chắc chắn sẽ biết NGINX còn được sử dụng để làm proxy cho Passenger, Unicorn hay THIN.

Ở đây, chúng ta sẽ sử dụng Apache để xử lý PHP thông qua module mod_php của nó, còn NGINX sẽ có nhiệm vụ đọc dữ liệu nhận được, xử lý các file tĩnh, cache (NGINX làm rất tốt trong việc xử lý cache).

Nó hoạt động thế nào?

Như bạn cũng biết, trình duyệt sẽ đọc dữ liệu từ server truyền về thông qua cổng 80 và mặc định khi cài NGINX hay Apache nó cũng đều được sử dụng cổng này. Nhưng bây giờ, chúng ta sẽ cho Apache cho một cổng nào đó (8080 chẳng hạn) mà trình duyệt sẽ không đọc trực tiếp được, rồi chúng ta sẽ sử dụng cổng 80 cho NGINX, lúc này NGINX sẽ tự động gửi các truy vấn từ các file có đuôi mở rộng là .php đến cổng của Apache cho nó xử lý rồi Apache trả dữ liệu lại cho NGINX rồi NGINX gửi cho người dùng đọc.

Chi tiết cách cài đặt

Bây giờ, mình sẽ hướng dẫn các bạn cài đặt từ A đến Z một webserver sử dụng Apache và NGINX, cài đặt PHP và các extensions cần thiết. Riêng database thì bạn có thể cài MariaDB như bài này.

Chuẩn bị server

  • Hệ điều hành CentOS 6.5 (nếu bạn chọn CentOS 7 thì không thể làm theo hướng dẫn này, mình sẽ có tutorial riêng cho CentOS 7).
  • RAM tối thiểu 512MB và trung bình là 1GB.
  • User root.

Bước 1. Cài Apache và thiết lập

Ta tiến hành cài Apache vào trước nhé.

yum install httpd

Sau đó mở file /etc/httpd/conf/httpd.conf, tìm:

Listen 80

Sửa port 80 thành 8080.

Tiếp tục tìm:

# First, we configure the "default" to be a very restrictive set of
# features.
#
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>

Thay AllowOverride None thành AllowOverride All.

Ok, tạm lưu lại, bây giờ hãy tạo các thư mục chứa dữ liệu website để tí nữa ta sẽ thêm VirtualHost vào Apache. Ví dụ mình cần thêm example.com vào server với đường dẫn lưu là /home/example.com thì sẽ tạo như sau:

mkdir -p /home/example.com/public_html
mkdir -p /home/example.com/log
touch /home/example.com/log/error.log
chown -R apache:apache /home/example.com/

Tiếp tục mở lại file /etc/httpd/conf/httpd.conf và tìm dòng:

#NameVirtualHost *:80

Đổi thành:

NameVirtualHost *:8080

Nhìn ngay xuống dưới sẽ thấy đoạn này:

#<VirtualHost *:80>
# ServerAdmin webmaster@dummy-host.example.com
# DocumentRoot /www/docs/dummy-host.example.com
# ServerName dummy-host.example.com
# ErrorLog logs/dummy-host.example.com-error_log
# CustomLog logs/dummy-host.example.com-access_log common
#</VirtualHost>

Bỏ comment, thay port và đổi đường dẫn thành như dưới đây:

<VirtualHost *:8080>
ServerAdmin contact@thachpham.com
DocumentRoot /home/example.com/public_html
ServerName www.example.com
ServerAlias example.com
ErrorLog /home/example.com/log/error.log
# CustomLog logs/dummy-host.example.com-access_log common
</VirtualHost>

Xem hình chụp cho chắc cú nha:

nginxproxy apachevhost

Ok, bây giờ hãy lưu lại và kích hoạt Apache lên, và cho nó tự khởi động khi reboot.

service httpd start
chkconfig httpd on
[root@nginxproxy ~]# service httpd start Starting httpd: httpd: apr_sockaddr_info_get() failed for nginxproxy httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName [OK ]

Bạn có thể gõ netstat -ntlup để kiểm tra, nếu httpd đang đọc qua port 8080 là chính xác.

nginxproxy checkapacheport

Bước 2. Cài đặt NGINX và cấu hình

Mình sẽ sử dụng NGINX phiên bản mới nhất nên bạn cần nạp package này vào bằng cách tạo file /etc/yum.repos.d/nginx.repo rồi bỏ đoạn sau vào:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

Cài NGINX.

yum install nginx

Sau đó mở file /etc/nginx/conf.d/default.conf rồi xóa toàn bộ nội dung trong đó và copy đoạn dưới đây bỏ vào, mục đích là nhìn cho nó gọn hơn vì ta chỉ cần dùng vài chức năng thôi:

server {
    listen       80;
    server_name  example.com;
 
    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;
 
    location / {
                proxy_pass   http://111.222.333:8080;
    }
 
    #error_page  404              /404.html;
 
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
 
    location ~ \.php$ {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:8080;
    }
 
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}
 
    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\.ht {
        deny  all;
    }
}
  • Bạn hãy sửa lại thành domain của bạn ở dòng 03.
  • Sửa 111.222.333 thành IP server của bạn ở dòng 09.

Sau đó lưu lại và khởi động NGINX, đồng thời cho nó tự khởi động khi reboot:

service nginx start
chkconfig nginx on

Bước 3. Cài đặt PHP và các extensions liên quan

Cũng nên nói lại rằng mặc dù chúng ta sẽ sử dụng NGINX nhưng sẽ không cài PHP-FPM để làm handler cho NGINX để xử lý PHP mà đã có Apache lo rồi, do đó chúng ta chỉ cần cài PHP vào là đủ.

PHP ở đây mình sẽ dùng PHP 5.6 vì có thể sử dụng Opcache được.

Đầu tiên là nạp 2 package này vào:

rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

Sau đó cài php và php-mysql vào bằng lệnh dưới đây:

yum --enablerepo=remi,remi-php56 install php php-mysql php-devel php-gd

Nếu bạn thích thì có thể cài thêm một số software sau, có sẵn trong pack php56 rồi:

  • php-opcache: Zend Opcache.
  • php-pecl-apcu: APC Opcode Cache.
  • php-pecl-memcached: Memcached Server
  • php-pecl-memcache: Memcache Client

Lưu ý là các software trên đều nằm trong pack php56 mới nạp nhưng pack này không được kích hoạt nên bạn muốn cài phải gõ là:

yum --enablerepo=remi,remi-php56 install [tên-software]

Sau khi cài xong PHP (và các extensions nếu có), hãy gõ lệnh php -v để xem phiên bản hiện tại của PHP.

[root@nginxproxy ~]# php -v
PHP 5.6.2 (cli) (built: Oct 16 2014 09:08:04)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies

Bây giờ hãy tạo 1 file tên là info.php trong thư mục /home/example.com/public_html có nội dung là:

<php phpinfo(); ?>

Bây giờ hãy truy cập vào tên miền http://example.com/info.php và xem phần Server API có phải là Apache 2.0 Handler hay không, nếu phải thì thành công.

nginxproxy finish

Và hãy thử xem HTTP Header của file này xem có phải sử dụng NGINX hay không nhé.

curl -I http://111.222.333/info.php
HTTP/1.1 200 OK Server: nginx/1.7.6 Date: Tue, 21 Oct 2014 00:37:10 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive X-Powered-By: PHP/5.6.2

Ok, thành công rồi đó.

Giờ để có thể chạy được WordPress, bạn có thể cài MySQL hoặc MariaDB vào, mình khuyến khích dùng MariaDB.

Nếu bạn nào đang dùng Apache rồi và muốn áp dụng kỹ thuật này thì chỉ cần cài thêm NGINX (không khuyến khích làm nếu bạn dùng bất kỳ control panel nào như cPanel, DirectAdmin, Koloxo,….)

Fix lỗi redirect sang IP trên WordPress

Nếu bạn làm theo bài này mà bị lỗi Loop về IP của server thì hãy chèn đoạn sau vào file functions.php

remove_filter('template_redirect', 'redirect_canonical');

Và trong bài case study, mình đã có nói qua về các tham số để tối ưu PHP và MariaDB, bạn có thể xem rồi cấu hình theo.

Chúc bạn làm thành công

Theo thachpham.com