Giới thiệu Apache và Nginx là hai máy chủ web mã nguồn mở phổ biến thường được sử dụng với PHP. Nó có thể hữu ích để chạy cả hai cái cùng một máy ảo. Các giải pháp chung cho chạy hai máy chủ web trên một hệ thống duy nhất là một trong hai sử dụng nhiều địa chỉ IP hoặc số cổng khác nhau. Chúng tôi sẽ sử dụng bốn tên miền trên một Droplet. Hai sẽ được phục vụ bởi Nginx: example.com (mặc định máy chủ ảo) và sample.org. Hai cái còn lại,, foobar.net và test.io, sẽ được phục vụ bởi Apache. Bước 1 - Cài đặt Apache và PHP-FPM Ngoài Apache và PHP-FPM, chúng ta cũng phải cài đặt các module PHP FastCGI Apache được đặt tên libapache2-mod-fastcgi. Thứ nhất, cập nhật kho apt để đảm bảo bạn có các gói mới nhất. Mã: apt-get update Tiếp theo, cài đặt các gói cần thiết: Mã: apt-get install apache2 libapache2-mod-fastcgi php-fpm Tiếp theo, chúng ta hãy thay đổi cấu hình mặc định của Apache. Bước 2 - Cấu hình Apache và PHP-FPM Trong bước này, chúng ta sẽ thay đổi số cổng của Apache đến 8080 và cấu hình nó để làm việc với PHP-FPM sử dụng module mod_fastcgi. Chỉnh sửa các tập tin cấu hình Apache và thay đổi số cổng của Apache. Mã: nano /etc/apache2/ports.conf Tìm dòng sau: Mã: Listen 80 Thay đổi nó thành: Mã: Listen 8080 Lưu và thoát ports.conf. Tiếp theo chúng ta sẽ chỉnh sửa các tập tin mặc định máy chủ ảo của Apache. Mở tập tin máy chủ ảo mặc định. Mã: nano /etc/apache2/sites-available/000-default.conf Dòng đầu tiên là: Mã: <VirtualHost *:80> Thay đổi nó thành: Mã: <VirtualHost *:8080> Lưu tập tin và tải lại Apache. Mã: systemctl reload apache2 Xác minh rằng Apache đang lắng nghe trên 8080. Mã: netstat -tlpn Kết quả ra nên trông giống như ví dụ sau đây, với apache2 lắng nghe trên 8080 :::. Mã: Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1086/sshd tcp6 0 0 :::8080 :::* LISTEN 4678/apache2 tcp6 0 0 :::22 :::* LISTEN 1086/sshd Sau khi xác minh Apache đang lắng nghe trên cổng chính xác, bạn có thể cấu hình hỗ trợ cho PHP và FastCGI. Bước 3 - Cấu hình Apache để sử dụng mod_fastcgi Apache sử dụng mod_php theo mặc định để chạy php, nhưng ta cần cấu hình bổ sung để làm việc với PHP-FPM. Lưu ý: Nếu bạn đang cố gắng làm theo hướng dẫn này trên một cài đặt hiện có của LAMP với mod_php, vô hiệu hóa nó đầu tiên với: Mã: a2dismod php7.0 Chúng tôi sẽ có thêm một khối cấu hình cho mod_fastcgi mà phụ thuộc vào mod_action. mod_action bị tắt theo mặc định, vì vậy đầu tiên chúng ta cần phải kích hoạt nó. Mã: a2enmod actions Cấu hình cho các tập tin .php tới PHP-FPM UNIX socket. Mã: nano /etc/apache2/mods-enabled/fastcgi.conf Thêm các dòng sau đây trong khối <IfModule mod_fastcgi.c>. . . </ IfModule>, dưới mục hiện có trong khối đó: Mã: AddType application/x-httpd-fastphp .php Action application/x-httpd-fastphp /php-fcgi Alias /php-fcgi /usr/lib/cgi-bin/php-fcgi FastCgiExternalServer /usr/lib/cgi-bin/php-fcgi -socket /run/php/php7.0-fpm.sock -pass-header Authorization <Directory /usr/lib/cgi-bin> Require all granted </Directory> Lưu các thay đổi bạn đã thực hiện với fastcgi.conf và kiểm tra cấu hình. Mã: apachectl -t Tải lại Apache nếu Syntax OK được hiển thị. Nếu bạn nhìn thấy cảnh báo “Could not reliably determine the server's fully qualified domain name, using 127.0.1.1” . Thiết lập 'ServerName’ để ngăn chặn tin nhắn này. Mã: systemctl reload apache2 Bây giờ hãy chắc chắn rằng chúng tôi có thể sử dụng PHP từ Apache. Bước 4 – Xác nhận chức năng PHP Kiểm tra nếu PHP hoạt động bằng cách tạo ra một tập tin phpinfo() và truy cập nó từ trình duyệt web của bạn. Mã: echo "<?php phpinfo(); ?>" | tee /var/www/html/info.php Để xem các tập tin trong một trình duyệt, vào http://your_ip_address: 8080/info.php. Điều này sẽ cung cấp cho bạn một danh sách các thiết lập cấu hình PHP đang sử dụng. Ở phía trên cùng của trang, kiểm tra Server API hiển thị FPM/FastCGI. Đi xuống phía dưới ta sẽ tìm thấy đoạn được bao khung màu đỏ, dòng chỉ thị SERVER_SOFTWARE là Apache trên Ubuntu. Những điều này xác nhận mod_fastcgi đang hoạt động và Apache đang sử dụng PHP-FPM để xử lý các file PHP. Bước 5 - Tạo Virtual Host cho Apache Đầu tiên, tạo ra thư mục root: Mã: mkdir -v /var/www/{foobar.net,test.io} Sau đó tạo một tập tin index cho mỗi trang web. Mã: echo "Foo Bar" | tee /var/www/foobar.net/index.html echo "Test IO" | tee /var/www/test.io/index.html Sau đó tạo một file phpinfo() cho mỗi trang web để chúng tôi có thể kiểm tra PHP được cấu hình đúng. Mã: echo "<?php phpinfo(); ?>" | tee /var/www/foobar.net/info.php echo "<?php phpinfo(); ?>" | tee /var/www/test.io/info.php Bây giờ tạo ra tập tin máy chủ ảo cho các miền foobar.net. Mã: nano /etc/apache2/sites-available/foobar.net.conf Đặt chỉ thị sau đây trong tập tin mới này: Mã: <VirtualHost *:8080> ServerName foobar.net ServerAlias www.foobar.net DocumentRoot /var/www/foobar.net <Directory /var/www/foobar.net> AllowOverride All </Directory> </VirtualHost> Lưu ý: AllowOverride All cho phép hỗ trợ .htaccess. Lưu và đóng tập tin. Sau đó tạo một cấu hình tương tự cho test.io. Mã: nano /etc/apache2/sites-available/test.io.conf Mã: <VirtualHost *:8080> ServerName test.io ServerAlias www.test.io DocumentRoot /var/www/test.io <Directory /var/www/test.io> AllowOverride All </Directory> </VirtualHost> Bây giờ cả hai máy ảo Apache được thiết lập, cho phép các trang web bằng cách sử dụng lệnh a2ensite. Điều này tạo ra một liên kết đến tập tin máy chủ ảo trong thư mục sites-enabled. Mã: a2ensite foobar.net a2ensite test.io Kiểm tra Apache cho các lỗi cấu hình một lần nữa. Mã: apachectl -t Tải lại Apache nếu Syntax OK được hiển thị. Mã: systemctl reload apache2 Để xác nhận các trang web đang làm việc, mở http://foobar.net:8080 và http://test.io:8080 trong trình duyệt của bạn và xác minh rằng mỗi trang web sẽ hiển thị tập tin index.html của nó. Bạn sẽ thấy kết quả như sau: Ngoài ra, kiểm tra rằng PHP có làm việc hay không bằng cách truy cập tập tin info.php cho mỗi trang web. Mở http://foobar.net:8080/info.php và http://test.io:8080/info.php trong trình duyệt của bạn. Bước 6 - Cài đặt và cấu hình Nginx Trong bước này, chúng ta sẽ cài đặt Nginx và cấu hình các tên miền example.com và sample.org. Cài đặt nginx bằng lệnh sau: Mã: apt-get install nginx Sau đó, loại bỏ liên kết mặc định máy chủ ảo vì chúng ta sẽ không sử dụng nó nữa Mã: rm /etc/nginx/sites-enabled/default Đầu tiên tạo thư mục root cho cả 2 trang tên miền Mã: mkdir -v /usr/share/nginx/{example.com,sample.org} Chúng tôi tạo tập tin index và tập tin phpinfo() để kiểm tra sau khi thiết lập xong. Mã: echo "Example.com" | tee /usr/share/nginx/example.com/index.html Mã: echo "Sample.org" | tee /usr/share/nginx/sample.org/index.html Mã: echo "<?php phpinfo(); ?>" | tee /usr/share/nginx/example.com/info.php echo "<?php phpinfo(); ?>" | tee /usr/share/nginx/sample.org/info.php Bây giờ tạo ra một tập tin máy chủ ảo cho tên miền example.com. Mã: nano /etc/nginx/sites-available/example.com Dán sau vào tập tin cho example.com: Mã: server { listen 80 default_server; root /usr/share/nginx/example.com; index index.php index.html index.htm; server_name example.com www.example.com; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { fastcgi_pass unix:/run/php/php7.0-fpm.sock; include snippets/fastcgi-php.conf; } } Lưu và đóng tập tin. Bây giờ tạo ra một tập tin máy chủ ảo cho tên miền thứ hai sample.org. Mã: nano /etc/nginx/sites-available/sample.org Khối máy chủ cho sample.org nên trông như thế này: Mã: server { root /usr/share/nginx/sample.org; index index.php index.html index.htm; server_name sample.org www.sample.org; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { fastcgi_pass unix:/run/php/php7.0-fpm.sock; include snippets/fastcgi-php.conf; } } Lưu và đóng tập tin. Sau đó, cho phép cả các trang web bằng cách tạo liên kết đến thư mục sites-enabled. Mã: ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com ln -s /etc/nginx/sites-available/sample.org /etc/nginx/sites-enabled/sample.org Kiểm tra cấu hình Nginx: Mã: nginx -t Sau đó tải lại Nginx nếu OK sẽ được hiển thị. Mã: systemctl reload nginx Bây giờ truy cập file phpinfo() của máy ảo Nginx trong một trình duyệt web bằng cách truy cập http://example.com/info.php và http://sample.org/info.php. Nhìn dưới được bao bởi khung màu đỏ. ["SERVER_SOFTWARE"] nên hiển thị là nginx, nó sẽ chỉ ra rằng các tập tin đã được dùng trực tiếp bằng Nginx. [ "DOCUMENT_ROOT"] phải trỏ đến thư mục mà bạn đã tạo trước đó. Bước 7 - Cấu hình Nginx cho Virtual Host Apache Tạo một Nginx tập tin máy chủ ảo mới: Mã: nano /etc/nginx/sites-available/apache Thêm khối mã bên dưới Mã: server { listen 80; server_name foobar.net www.foobar.net test.io www.test.io; location / { proxy_pass http://your_server_ip: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; proxy_set_header X-Forwarded-Proto $scheme; } } Lưu file và cho phép máy chủ ảo mới này bằng cách tạo ra một liên kết. Mã: ln -s /etc/nginx/sites-available/apache /etc/nginx/sites-enabled/apache Kiểm tra cấu hình: Mã: nginx -t Tải lại Nginx nếu OK sẽ được hiển thị. Mã: systemctl reload nginx Mở trình duyệt và truy cập vào URL http://foobar.net/info.php trong trình duyệt của bạn. Cuộn xuống phần PHP Variables và kiểm tra giá trị hiển thị. Các biến chủ SERVER_SOFTWARE và DOCUMENT_ROOT xác nhận rằng yêu cầu này đã được xử lý bởi Apache. Các biến HTTPXREAL_IP và HTTPXFORWARDED_FOR đã được thêm bởi Nginx và sẽ hiển thị địa chỉ IP public của máy tính bạn đang sử dụng để truy cập vào URL. Bước 8 - Cài đặt và cấu mod_rpaf Cài đặt các gói cần thiết để xây dựng các mô-đun: Mã: apt-get install unzip build-essential apache2-dev Tải về phiên bản mới nhất từ GitHub. Mã: wget https://github.com/gnif/mod_rpaf/archive/stable.zip Giải nén nó với: Mã: unzip stable.zip Chuyển đến thư mục cài đặt: Mã: cd mod_rpaf-stable Sau đó biên dịch và cài đặt các module. Mã: make make install Tạo một tập tin trong thư mục mods-available Mã: nano /etc/apache2/mods-available/rpaf.load Thêm dòng sau vào file: Mã: LoadModule rpaf_module /usr/lib/apache2/modules/mod_rpaf.so Tạo một tập tin trong thư mục này. Điều này sẽ chứa các chỉ dẫn cấu hình. Mã: nano /etc/apache2/mods-available/rpaf.conf Thêm khối mã sau: Mã: <IfModule mod_rpaf.c> RPAF_Enable On RPAF_Header X-Real-Ip RPAF_ProxyIPs your_server_ip RPAF_SetHostName On RPAF_SetHTTPS On RPAF_SetPort On </IfModule> Dưới đây là một mô tả ngắn gọn của từng chỉ thị. RPAF_Header - Các tiêu đề để sử dụng cho địa chỉ IP thực của khách hàng. RPAF_ProxyIPs - IP proxy để điều chỉnh các yêu cầu HTTP . RPAF_SetHostName - Cập nhật các tên vhost để ServerName và ServerAlias làm việc. RPAF_SetHTTPS - Thiết lập các biến môi trường HTTPS dựa trên các giá trị chứa trong X-Forwarded-Proto. RPAF_SetPort - Thiết lập các biến môi trường SERVER_PORT Lưu rpaf.conf và cho phép các module. Mã: a2enmod rpaf Điều này tạo ra các liên kết của các tập tin và rpaf.load rpaf.conf trong thư mục mods-enabled. Bây giờ kiểm tra cấu hình. Mã: apachectl -t Tải lại Apache nếu Syntax OK được trả về. Mã: systemctl reload apache2 Truy cập một trong các trang web phpinfo() của Apache trong trình duyệt của bạn và kiểm tra phần PHP Variables. Biến REMOTE_ADDR bây giờ cũng có giá trị là địa chỉ IP public máy tính của bạn. Bước 9 - Thiết lập HTTPS Websites (Tùy chọn) Trong bước này, chúng ta sẽ cấu hình chứng chỉ SSL cho cả hai tên miền được lưu trên Apache. Nginx hỗ trợ kết thúc SSL vì vậy chúng tôi có thể thiết lập SSL mà không sửa đổi các file cấu hình của Apache. Tạo một thư mục cho các chứng chỉ SSL và khóa riêng Mã: mkdir /etc/nginx/ssl Đối với bài viết này, chúng tôi sẽ sử dụng chứng chỉ SSL tự tạo với giá trị thời gian trong 10 năm. Tạo chứng chỉ tự ký cho cả hai foobar.net và test.io. Mã: openssl req -x509 -sha256 -newkey rsa:2048 -keyout /etc/nginx/ssl/foobar.net-key.pem -out /etc/nginx/ssl/foobar.net-cert.pem -days 3650 -nodes openssl req -x509 -sha256 -newkey rsa:2048 -keyout /etc/nginx/ssl/test.io-key.pem -out /etc/nginx/ssl/test.io-cert.pem -days 3650 -nodes Mỗi lần, bạn sẽ được nhắc nhở để xác định chi tiết chứng chỉ. Nhập tên miền phù hợp với Common Name. Mã: Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:New York Locality Name (eg, city) []:New York City Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean Inc Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:foobar.net Email Address []: Bây giờ mở tập tin máy ảo Apache Mã: nano /etc/nginx/sites-available/apache Kể từ khi chúng tôi có giấy chứng nhận riêng biệt và các khóa cho từng tên miền, chúng ta cần phải có khối máy chủ riêng biệt {. . . } cho từng domain. Bạn nên xóa nội dung hiện tại của tập tin và thay thế nó với những nội dung sau đây: Mã: server { listen 80; listen 443 ssl; server_name test.io www.test.io; ssl on; ssl_certificate /etc/nginx/ssl/test.io-cert.pem; ssl_certificate_key /etc/nginx/ssl/test.io-key.pem; location / { proxy_pass http://your_server_ip: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; proxy_set_header X-Forwarded-Proto $scheme; } } server { listen 80; listen 443 ssl; server_name foobar.net www.foobar.net; ssl on; ssl_certificate /etc/nginx/ssl/foobar.net-cert.pem; ssl_certificate_key /etc/nginx/ssl/foobar.net-key.pem; location / { proxy_pass http://your_server_ip: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; proxy_set_header X-Forwarded-Proto $scheme; } } Chúng tôi tách ra khối máy chủ gốc thành hai khối riêng biệt, và chúng tôi cũng đã cấu hình Nginx để lắng nghe trên cổng 443, cổng mặc định cho các trang web an toàn. Lưu file và thực hiện kiểm tra cấu hình. Mã: nginx -t Tải lại Nginx nếu thử nghiệm thành công. Mã: systemctl reload nginx Bây giờ, truy cập vào một trong domain của Apache trong trình duyệt của bạn. Đầu tiên, hãy truy cập https://foobar.net/info.php và bạn sẽ thấy điều này: Kiếm phần PHP Variables. Biến SERVER_PORT đã được thiết lập đến 443 và HTTPS được thiết lập on, điều này cho thấy Apache đã trực tiếp truy cập qua HTTPS. Bước 10 - Chặn truy cập trực tiếp đến Apache (Tùy chọn) Kể từ khi Apache đang lắng nghe ở cổng 8080 trên địa chỉ IP public, nó có thể truy cập bởi tất cả mọi người. Điều này rất nguy hiểm vì thê ta nên sử dụng iptables để chặn bằng lệnh sau: Mã: iptables -I INPUT -p tcp --dport 8080 ! -s [B]your_server_ip[/B] -j REJECT --reject-with tcp-reset Hãy đảm bảo sử dụng địa chỉ IP Droplet của bạn ở đoạn tô đậm phía trên . Khi cổng 8080 bị chặn bởi tường lửa của bạn, Apache sẽ không thể truy cập vào nó. Mở trình duyệt web của bạn và cố gắng truy cập vào một trong các tên miền của Apache trên cổng 8080. Ví dụ: http://example.com:8080 Các trình duyệt sẽ hiển thị một thông báo lổi "Unable to connect" hoặc "Webpage is not available". Bước 11 - Chạy tập tin tĩnh sử dụng Nginx (Tùy chọn) Nginx là nhanh hơn so với Apache trong việc chạy các tập tin tĩnh như hình ảnh, JavaScript và style sheets. Vì vậy, hãy cấu hình tập tin máy chủ ảo Nginx's apache để phục vụ trực tiếp các tập tin tĩnh. Trước tiên, mở file host ảo apache. Mã: nano /etc/nginx/sites-available/apache Bạn sẽ cần phải thêm hai khối bổ sung cho mỗi khối máy chủ, và sửa đổi các khối vị trí hiện tại. Ngoài ra, bạn sẽ cần cấu hình Nginx để chỉ ra nơi tìm các tập tin tĩnh cho mỗi trang web . Những thay đổi này được thể hiện bằng đoạn tô đậm trong đoạn code sau: Mã: server { listen 80; server_name test.io www.test.io; [B]root /var/www/test.io;[/B] [B]index index.php index.htm index.html;[/B] [B]location / {[/B] [B]try_files $uri $uri/ /index.php;[/B] [B]}[/B] [B]location ~ \.php$ {[/B] proxy_pass http://your_ip_address: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; proxy_set_header X-Forwarded-Proto $scheme; } [B]location ~ /\. {[/B] [B]deny all;[/B] [B]}[/B] } server { listen 80; server_name foobar.net www.foobar.net; [B]root /var/www/foobar.net;[/B] [B]index index.php index.htm index.html;[/B] [B]location / {[/B] [B]try_files $uri $uri/ /index.php;[/B] [B]}[/B] [B]location ~ \.php$[/B] [B]{[/B] proxy_pass http://your_ip_address: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; proxy_set_header X-Forwarded-Proto $scheme; } [B]location ~ /\. {[/B] [B]deny all;[/B] [B]}[/B] } Lưu file và thực hiện kiểm tra cấu hình. Mã: nginx -t Tải lại Nginx nếu thử nghiệm thành công. Mã: service nginx reload Để xác minh điều này đang làm việc, bạn có thể kiểm tra các file log của Apache trong /var/log/apache2 và xem các yêu cầu GET cho các file info.php của test.io và foobar.net. Sử dụng câu lệnh sau: Mã: tail -f /var/log/apache2/other_vhosts_access.log Mở http://test.io/info.php trong trình duyệt của bạn và sau đó nhìn vào kết quả output từ nhật ký. Bạn sẽ thấy rằng Apache đang thực sự trả lời: Mã: test.io:80 your_server_ip - - [01/Jul/2016:18:18:34 -0400] "GET /info.php HTTP/1.0" 200 20414 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36" Sau đó truy cập vào trang index.html cho mỗi trang web và bạn sẽ không thấy bất kỳ mục nào liên quan đến Apache. Nginx đã làm tốt công việc.