Apache xuất hiện từ năm 2006 và hiện đang là webserver được sử dụng nhiều nhất trên thế giới, tiếp theo đó là vị trí số #2 thuộc về Nginx. Mỗi webserver có ưu điểm riêng, Apache với khả năng xử lý mạnh mẽ còn Nginx có tốc độ vượt trội, đặc biệt với những file tĩnh.

Mặc dù hiện tại chúng ta có thể thay thế hoàn toàn Nginx cho Apache, tuy nhiên vì một số lí do nên nhiều người vẫn bắt buộc phải dùng Apache. Và giải pháp tối ưu lúc này đó là sử dụng Nginx làm Reverse Proxy cho Apache.

Lúc này, Nginx đóng vai trò làm front end xử lý các file tĩnh, còn Apache làm back end xử lý dynamic content.

nginx-as-a-reverse-proxy-for-apache

 

1. Cài đặt Apache

Nếu VPS chưa được cài đặt Apache thì bạn dùng lệnh sau để cài đặt:

yum install httpd httpd-devel

2. Cấu hình Reverse Proxy trên Apache

– Chỉnh cổng mặc định 80 của Apache thành 8080

nano /etc/httpd/conf/httpd.conf

Tìm dòng Listen 80 và thay bằng Listen 8080

– Sau đó, di chuyển đến cuối file và dán những dòng sau vào để tạo mới một virtual host:

NameVirtualHost *:8080
 
<VirtualHost *:8080>
   ServerName example.com
   ServerAlias www.example.com
   DocumentRoot /var/www/html
       <Directory "/var/www/html">
               Options FollowSymLinks -Includes
               AllowOverride All
               Order allow,deny
               Allow from all
       </Directory>
       RewriteEngine on
</VirtualHost>

– Lưu lại file cấu hình và khởi động lại Apache

service httpd restart

3. Cài đặt Nginx

Thêm repo EPEL

yum install epel-release

– Cài đặt Nginx

yum install nginx

4. Cấu hình Reverse Proxy trên Nginx

– Tạo Nginx virtual host

nano /etc/nginx/conf.d/example.com.conf

với nội dung như bên dưới:

server {
   listen 80;
   server_name example.com;
   access_log off;
   error_log off;

   location / {
      client_max_body_size 10m;
      client_body_buffer_size 128k;
 
      proxy_send_timeout 90;
      proxy_read_timeout 90;
      proxy_buffer_size 128k;
      proxy_buffers 4 256k;
      proxy_busy_buffers_size 256k;
      proxy_temp_file_write_size 256k;
      proxy_connect_timeout 30s;
 
      proxy_redirect http://www.example.com:8080 http://www.example.com;
      proxy_redirect http://example.com:8080 http://example.com;
 
      proxy_pass http://127.0.0.1:8080/;
 
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }

   # Select files to be deserved by nginx
   location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|txt|srt|swf|zip|rar|html|htm|pdf)$ {
      root /var/www/html;
      expires 30d; # caching, expire after 30 days
   }
}

– Kiểm tra và khởi động lại Nginx

nginx -t
service nginx restart

5. Cài đặt module Reverse Proxy And Forward cho Apache

Để Apache có thể hiểu được traffic đang đến từ đâu, chúng ta cần cài thêm module rpaf (Reverse Proxy And Forward). rpaf sẽ nhận X-Forwarded-For header từ proxy server và điều chỉnh lại remote address của client.

Cài đặt httpd-devel và gcc để compile source:

yum install httpd-devel gcc

Tải về mod_rpaf. Xem phiên bản mới nhất ở đây.

wget http://mirror.trouble-free.net/sources/mod_rpaf-0.6.tar.gz
tar zxvf mod_rpaf-0.6.tar.gz
cd mod_rpaf-0.6
apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

Link dự phòng: https://hocvps.com/wp-content/uploads/2015/05/mod_rpaf-0.6.tar.gz

Nếu thành công bạn sẽ thấy thông báo như sau:

mod_rpaf

Tiếp theo bạn hãy tạo file cấu hình cho mod_rpaf

nano /etc/httpd/conf.d/mod_rpaf.conf

Với nội dung như sau (chú ý thay 1.2.3.4 bằng IP server của bạn):

LoadModule rpaf_module modules/mod_rpaf-2.0.so

# mod_rpaf Configuration

RPAFenable On
RPAFsethostname On
RPAFproxy_ips 1.2.3.4
RPAFheader X-Forwarded-For

Cuối cùng khởi động lại Apache là xong

service httpd restart

6. Kiểm tra kết quả

– Nếu cài đặt thành công, khi truy cập vào domain example.com chúng ta sẽ thấy trang mặc định của Apache

Apache 2 Test Page

– Và test phpinfo (cần cài đặt PHP trước, tham khảo hướng dẫn cài LAMP)

nano /var/www/html/info.php

//Paste đoạn sau vào
<?php phpinfo(); ?>

PHP info

Như vậy là xong rồi đó, công việc tiếp theo của chúng ta là thực hiện tối ưu cho webserver Apache và Nginx; cài đặt thêm module cần thiết khác.

Tham khảo thêm:

Chúc các bạn thành công!

Comment của bạn

Lưu ý: tất cả comment đều được kiểm duyệt cẩn thận! Nếu có code bạn hãy up lên pastebin.com rồi để lại link trong comment.

60 Comments

  1. Trung 3 comment

    Admin cho mình hỏi:

    Centos 7 đã cài Apache 2 rồi, thư mục website đã có rồi, thì mình chỉ cần thay đổi vhost -> rồi cài thêm Nginx, cấu hình Nginx theo các bước là được đúng không ạ? (Mình dùng chỉ 1 VPS)

    Xin giải đáp giúp mình với!!

      1. Trung 3 comment

        Ah vậy mình dùng hocvps scripts để cài Nginx, rồi theo bài này cài làm proxy là được đúng không ạ?

  2. phương 1 comment

    NameVirtualHost *:8080

    ServerName example.com
    ServerAlias http://www.example.com
    DocumentRoot /var/www/html

    Options FollowSymLinks -Includes
    AllowOverride All
    Order allow,deny
    Allow from all

    RewriteEngine on

    admin hướng dẫn mình thêm đoạn này. khi mình thêm vào cuối file /etc/httpd/conf/httpd.conf xong thì restart apache lại nó báo lỗi

  3. Thoại 3 comment

    Chào bạn,
    Cho mình hỏi nhờ: khi cài SSL thì cài cho Apache hay Nginx ?
    Mình đã thử thì thấy cần phải cài cho cả Apache và Nginx, nhưng đến SSL cho web thứ hai thì lại bị lỗi.
    Mong bạn chia sẻ mình xin ít kinh nghiệm hoặc tài liệu (tiếng Anh cũng được)

    Cảm ơn bạn nhiều

  4. Anh Nguyen 2 comment

    Cho mình hỏi trước mình có nhớ Luân có chia sẻ ở đâu đó một vấn đề về giải quyết chuyện đứt cáp bằng cách tạo 1 Reverse Proxy cho web.
    Vậy mình có trường hợp này ko biết có xử lý được ko.
    Mình có 1 VPS chạy Apache + Nginx đặt tại nhật, nếu mọi chuyện bt ko đứt cáp vân vân mây mây thì thì cho chạy trưc tiếp VPs này luôn
    Và hiện mình có 1 VPS tại VN, trường hợp đứt cáp xảy ra có cách nào mình cấu hình để VPS tại nhật đi qua con VPS tại VN để tăng tốc độ truy cập ko, hoặc dùng con VPS VN là Reverse Proxy cho con của Nhật.
    Cảm ơn bạn.

    1. Việt Phương Moderator

      Thường ít cấu hình như thế. Giờ tiện lợi nhất là dùng CDN rồi bạn nhé

  5. đức 31 comment

    a cho e hỏi là nếu cấu hình như này, giả sử e thêm tên miền ducmu.info

    thì e nhận thấy rằng toàn bộ cái /var/www/html/ sẽ là ducmu.info

    ví dụ e ném abc.html vào /var/www/html/ thì sẽ truy cập nó qua ducmu.info/abc.html

    vậy nếu e thêm domain thứ 2 thì nó sẽ nằm ở chỗ nào và cách thêm thế nào ạ?

    1. Việt Phương Moderator

      Bạn cấu hình riêng lẻ từng Apache và Nginx cho từng domain. Bên Apache thì là DocumentRoot còn Nginx là root
      Khi đó bạn thích nó là thư mục nào nó sẽ là thư mục đó, không nhất thiết là /var/www/html
      Ví dụ, bạn quy định site1 DocumentRootroot/var/www/html/1
      Còn site2 DocumentRootroot/var/www/html/2

  6. hòa lê 1 comment

    Mình muốn làm cho chạy 2 website riêng biệt thì nên cấu hình ra sao, Mong bạn chỉ giúp.

    1. Việt Phương Moderator

      Bạn cấu hình Virtual Host site 2 tương tự như site 1 thôi, vẫn là Apache 8080 và Nginx 80

  7. Thịnh 2 comment

    Mình có một VPS dùng VestaCP Apache và Nginx và 1 thư mục web fame work YII

    Nhưng khi mình deploy lên thì báo (mặc dù mình đã làm mọi cách trên mạng chỉ nhưng không được)
    => Nhờ cao nhân giúp đỡ…^^ team view thì càng tốt

    Forbidden
    You don’t have permission to access / on this server.
    Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
    Apache/2.2.15 (CentOS) Server at camnangmuasam.ga Port 80

    1. Việt Phương Moderator

      Thư mục đó không thuộc quyền sở hữu của Webserver thì phải?

        1. Việt Phương Moderator

          Bạn kiểm tra xem thư mục đó thuộc quyền sở hữu của user:group nào, nếu không thuộc webserver thì chown nó đi

  8. Phat Pham 2 comment

    Luân cho hỏi sao mình compile mod_rpaf-0.6 như hướng dẫn mà nó cứ báo lỗi y như sinhle đã post vậy. Minh đang xài CentOS 7 64 bit. Mong Luân hay Việt Phương chỉ cách sửa.

  9. Phat Pham 2 comment

    Luân cho mình hỏi: Bài hướng dẫn này làm trên centOS 7 được không? Mới tập làm VPS nên không rành lắm.

    1. Việt Phương Moderator

      OK bạn nhé. Cent7 thì chú ý 1 số câu lệnh có thể thay đổi, như service thành systemctl…

  10. Hau Huynh 2 comment

    Cho Mình hỏi nếu mình có Apache Servẻ (192.168.1.21:8080) và NGINX Server ( 192.168.1.21:80) thì phải chỉnh dòng nào ở file cầu hình. Thanks

    1. Việt Phương Moderator

      Các cấu hình Vhost đều không cần chỉnh host, chỉ chỉnh port thôi mà bạn? Bạn là cài đặt trên máy cá nhân để test?

      1. Hau Huynh 2 comment

        Thanks, bạn đã quan tâm. Mình đang làm lab nếu thành công sẽ làm luôn thực tế. Bán có thể giải thích rõ hơn ko? Mình muốn tạo 1 con để làm hosting (192.168.1.21) và 1 con để làm nginx reverse proxy ( 192.168.1.22). Mình sẽ trỏ domain về con NGINX. Khi user truy cập vô website thì nó sẽ thông qua con NGINX để hiển thị lên con apache(Ko public ra internet).

  11. Tín 2 comment

    admin xin hướng dẫn em cách chạy máy chủ NGINX để điều khiển 2 máy webserver theo yêu cầu của người ra đề, tắt máy web1, thông tin web1 sẽ nhảy sang web2. Xin giúp em, please!

    1. Việt Phương Moderator

      Bạn nghiên cứu về load balancing nhé, đáp ứng được yêu cầu của bạn

  12. Tín 2 comment

    cho hỏi chạy nginx làm proxy cho apache trên máy linux Ubuntur 16.04 đc ko ad ơi?

  13. sinhle 71 comment

    mình chạy dòng lệnh “apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c”
    nó lỗi/usr/lib64/apr-1/build/libtool –silent –mode=compile gcc -std=gnu99 -prefer-pic -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong –param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -DLINUX -D_REENTRANT -D_GNU_SOURCE -pthread -I/usr/include/httpd -I/usr/include/apr-1 -I/usr/include/apr-1 -c -o mod_rpaf-2.0.lo mod_rpaf-2.0.c && touch mod_rpaf-2.0.slo
    mod_rpaf-2.0.c: In function ‘rpaf_cleanup’:
    mod_rpaf-2.0.c:150:23: error: ‘conn_rec’ has no member named ‘remote_ip’
    rcr->r->connection->remote_ip = apr_pstrdup(rcr->r->connection->pool, rcr->old_ip);
    ^
    mod_rpaf-2.0.c:151:23: error: ‘conn_rec’ has no member named ‘remote_addr’
    rcr->r->connection->remote_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(rcr->r->connection->remote_ip);
    ^
    mod_rpaf-2.0.c:151:5: warning: implicit declaration of function ‘inet_addr’ [-Wimplicit-function-declaration]
    rcr->r->connection->remote_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(rcr->r->connection->remote_ip);
    ^
    mod_rpaf-2.0.c:151:95: error: ‘conn_rec’ has no member named ‘remote_ip’
    rcr->r->connection->remote_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(rcr->r->connection->remote_ip);
    ^
    mod_rpaf-2.0.c: In function ‘change_remote_ip’:
    mod_rpaf-2.0.c:164:34: error: ‘conn_rec’ has no member named ‘remote_ip’
    if (is_in_array(r->connection->remote_ip, cfg->proxy_ips) == 1) {
    ^
    mod_rpaf-2.0.c:169:9: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    } else if (fwdvalue = apr_table_get(r->headers_in, “X-Forwarded-For”)) {
    ^
    mod_rpaf-2.0.c:183:73: error: ‘conn_rec’ has no member named ‘remote_ip’
    rcr->old_ip = apr_pstrdup(r->connection->pool, r->connection->remote_ip);
    ^
    mod_rpaf-2.0.c:186:26: error: ‘conn_rec’ has no member named ‘remote_ip’
    r->connection->remote_ip = apr_pstrdup(r->connection->pool, ((char **)arr->elts)[((arr->nelts)-1)]);
    ^
    mod_rpaf-2.0.c:187:26: error: ‘conn_rec’ has no member named ‘remote_addr’
    r->connection->remote_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(r->connection->remote_ip);
    ^
    mod_rpaf-2.0.c:187:93: error: ‘conn_rec’ has no member named ‘remote_ip’
    r->connection->remote_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(r->connection->remote_ip);
    ^
    mod_rpaf-2.0.c:190:17: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    if (hostvalue = apr_table_get(r->headers_in, “X-Forwarded-Host”)) {
    ^
    mod_rpaf-2.0.c:195:17: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    } else if (hostvalue = apr_table_get(r->headers_in, “X-Host”)) {
    ^
    apxs:Error: Command failed with rc=65536

    nhờ ad chỉ giúp. mnihf đang dùng sentora trên sentos 7

  14. Hai 3 comment

    mình đang dùng hocvps script chạy 4 web trên vps giờ cài thêm Apache như trên có dc ko vì có 2 site ko tương thích hoàn toàn với nginx

    1. Luân Trần Admin

      Thường nếu chạy được trên Apache thì chạy được trên Nginx đó bạn. Nếu do vấn đề rewrite URL thì bạn hãy chuyển rule sang Nginx mà chạy.

      1. Hai 3 comment

        em dùng code dle ( DataLife Engine ) 10.4 mọi thứ bt nhưng ko thể mở trang bấm vào link chỉ ra trang chủ , đang ko biết fix kiểu gi

  15. thanh 5 comment

    Sao mình làm tới phần tạo virtual host cho nginx thì test nginx -t ok.Mà restart nginx thì nó lại báo failed?

    nginx: [emerg] open() “/usr/share/nginx/off” failed (13: Permission denied)

    Move file .conf đã tạo ra chỗ khác thì restart bình thường còn bỏ vào là cứ restart là báo lỗi.Bạn có biết vì sao k?

    1. Luân Trần Admin

      Có thể file cấu hình đó có sử dụng folder /usr/share/nginx/off. Mà folder này không tồn tại hoặc nginx không có quyền đọc ghi ở đây.
      Bạn check thử xem

      1. Tuan 3 comment

        minh cung bi loi nay , minh chmod 777 luon nhung bi loi nay, minh cd vao thi co thay, nhung no bao loi denied.

  16. trung 1 comment

    Bài này hướng dẫn trên mô hình 1 máy chủ vps phải ko bạn ? Mình muốn tách nginx và apache sang 2 máy chủ khác nhau. và đang gặp vấn đề nginx không tìm thấy ảnh do đang nằm ở apache và responsive time cũng tăng lên. Bạn có kinh nghiệm trong việc này ko

    1. Luân Trần Admin

      Nếu dùng trên 2 máy chủ thì cần phải enable private network và sử dụng IP LAN để tăng thời gian xử lý, không tốn băng thông bạn ạ.

  17. duongthe 16 comment

    Mình cấu hình theo cách của bạn, từ đầu đến cuối đều ok hết. Chạy info.php cũng ok.
    Đến lúc import database vào, ko hiểu phải do database của mình lớn quá ko mà khi vào web thì tải rất lâu rồi báo lỗi 504.
    Mình đã chỉnh file: /etc/nginx/nginx.conf

    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    proxy_read_timeout 600;
    send_timeout 600;
    fastcgi_read_timeout 600;

    Nhưng vẫn ko được. Bạn có thể giúp mình dc chứ

      1. duongthe 16 comment

        Mình import database thì ok rồi. Nhưng khi vào web thì lỗi 504 thôi bạn à.

          1. duongthe 16 comment

            Cấu hình thì chuẩn rồi. Chạy dc lên file ìnfo.php như trong hướng dẫn của bạn mà. Có cái hàm này. Nếu bỏ đi thì ko bị 504, nhưng sẽ ko tải dc 1 số thành phần của web:

            public function get_widgets($position=null,$rank=null){
            $ps = array(‘header’=>1,’content’=>2,’sidebar’=>3,’footer’=>4,’custom’=>5);
            $p = strtolower($position);
            if(!is_null($position)&&!is_numeric($position)){
            if(isset($ps[$p]))
            $position = $ps[$p];
            }
            if(!is_numeric($position)) $position = 5;

            if(is_numeric($position)){
            db_where(‘position’,$position);
            }
            if(is_numeric($rank))
            db_where(‘rank’,$rank);
            db_orderby(‘rank’,’ASC’);
            db_orderby(‘id’,’DESC’);
            $___widgets___ = db_get(‘widgets’);
            $___vars___ = $this->vars;
            if(is_array($___vars___) && $___widgets___){
            $___e___ = “”;
            foreach($___vars___ as $k => $v){
            $___e___ .= “\$$k = \$___vars___[\”$k\”];”;
            }
            eval($___e___);
            }
            if($___widgets___){
            foreach($___widgets___ as $wid){
            $___file___ = ”;
            $g = THEMEDIR.’widgets/’.$wid[‘filename’];
            if(file_exists($g)) $___file___ = $g;
            elseif(file_exists($g.”.php”)) $___file___ = $g.”.php”;
            if($___file___ != ”){
            assign(‘widget_code’,$wid[‘code’]);
            include($___file___);
            assign(‘widget_code’,”);
            }
            }
            }
            }

          2. Luân Trần Admin

            Khả năng do theme, bạn thử chuyển sang dùng theme khác xem có bị tình trạng này ko?

          3. duongthe 16 comment

            Themes thì mình nghĩ chưa hẳn. Mình chạy web này tương tự trên hosting ssd tenten thì ok. Thực sự là thấy mệt mỏi với VPS quá.
            Bạn cho hỏi thêm là nếu VPS Ram 2GB, 2 CPU cài LAMP thì chịu tải được tối đa bao nhiêu người 1 lúc ?
            Web mình code tương tự thế này: http://www.thegioivuong.vn
            Mình chạy SSD host của tenten thì khoảng 400-500 người 1 lúc là có dấu hiệu bị lỗi 500.

          4. Luân Trần Admin

            Bạn thử chuyển qua sử dụng theme khác là biết ngay thôi.

            Câu hỏi chịu được bao nhiêu người online thì mình chịu thua nhé, vì không có công thức nào tính được cả.

  18. Thinh 5 comment

    Mình cài cái này ko dc nhỉ yum install mod_rpaf
    Nó hiện No package mod_rpaf available

    1. Luân Trần Admin

      Bạn chạy lệnh này chưa thế: wget -q -O - http://www.atomicorp.com/installers/atomic | sh

  19. Thomanphan 19 comment

    Có tools tự động như hocvps không, có cái này tiện hơn toàn nginx hơn nhiều.