介绍
Apache 和 Nginx 是常用 PHP 的两种流行的开源 Web 服务器,在托管具有不同要求的多个网站时,在相同的虚拟机上运行它们可以是有用的。
具有 IPv4 和 IPv6 地址的 dropplets 可以配置为在一个协议上的 Apache 站点和在另一个协议上的 Nginx 站点提供服务,但这目前并不实用,因为 ISP 的 IPv6 采用仍然不普遍。为第二个 Web 服务器提供不同的端口号,如 81 或
8080 是另一个解决方案,但与端口号共享 URL(如 http://example.com:81
)并不总是合理或理想的。
本教程将向您展示如何将 Nginx 配置为 Web 服务器和 Apache 的反向代理服务器 - 所有在一个 Droplet 上。 根据 Web 应用程序,可能需要对代码进行更改,以保持 Apache 反向代理服务器的警惕,特别是当配置 SSL 站点时。
我们将在一个Droplet上托管四个域名,其中两个将由Nginx提供服务:‘example.com’(默认虚拟主机)和‘sample.org’.其余两个,‘foobar.net’和‘test.io’,将由Apache提供服务。
前提条件
- 一个新的Ubuntu 14.04 Droplet。
- 具有`sudo'权限的标准用户账户。 您可以通过遵循 [初始服务器设置与 Ubuntu 14.04] (https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-14-04) 中的步骤2和步骤3来建立标准账户.
- 联合国 想要的域名应该指向您Droplet在 DigitalOcean 控制面板上的IP地址. 请参看如何用数字海洋设置主机名的第3步,以说明如何这样做。 如果您在其它地方主机域的 DNS, 您应该创建适当的_ A 记录_ 那里 。 .
可选参考
本教程需要对Apache和Nginx中的虚拟主机的基本知识,以及SSL证书的创建和配置。
第1步:安装Apache和PHP5-FPM
除了Apache和PHP-FPM之外,我们还必须安装PHP FastCGI Apache模块,这是libapache2-mod-fastcgi
,可在Ubuntu的 multiverse 存储库中使用,首先必须在sources.list
文件中启用。
1sudo nano /etc/apt/sources.list
查找下面的行,并通过在开始时删除哈希符号(#
)来消除评论。
1# deb http://mirrors.digitalocean.com/ubuntu trusty multiverse
2
3 . . .
4
5# deb http://mirrors.digitalocean.com/ubuntu trusty-updates multiverse
这应该留给你下面所示的东西。
1deb http://mirrors.digitalocean.com/ubuntu trusty multiverse
2
3 . . .
4
5 deb http://mirrors.digitalocean.com/ubuntu trusty-updates multiverse
保存文件并更新 apt 存储库。
1sudo apt-get update
然后安装必要的包。
1sudo apt-get install apache2 libapache2-mod-fastcgi php5-fpm
第2步:配置Apache和PHP5-FPM
在此步骤中,我们将更改Apache的端口号为8080
,并使用mod_fastcgi
模块将其配置为PHP5-FPM。
1sudo nano /etc/apache2/ports.conf
找下面的线条:
1Listen 80
把它改成:
1Listen 8080
保存并退出ports.conf
。
注意:网页服务器在配置反向代理时通常会听127.0.0.1:8080
,但这样做会将PHP的环境变量 SERVER_ADDR** 的值设置为循环 IP 地址,而不是服务器的公共 IP。
接下来,我们将编辑Apache的默认虚拟主机文件. 该文件中的<VirtualHost>
指令设置为仅在端口80
上服务网站。
1sudo nano /etc/apache2/sites-available/000-default.conf
第一行应该是:
1<VirtualHost *:80>
把它改成:
1<VirtualHost *:8080>
保存文件并重新加载Apache。
1sudo service apache2 reload
检查Apache是否正在听8080
。
1sudo netstat -tlpn
输出应如下所示,以 apache2 倾听为** :::8080** 。
1Active Internet connections (only servers)
2Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
3tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1086/sshd
4tcp6 0 0 :::8080 :::* LISTEN 4678/apache2
5tcp6 0 0 :::22 :::* LISTEN 1086/sshd
步骤 3 — 配置 Apache 以使用 mod_fastcgi
Apache 默认情况下使用mod_php
,但需要额外的配置才能使用 PHP5-FPM。
注意: 如果您正在尝试使用mod_php
在现有LAMP安装上使用此教程,请先禁用它: > ``` > sudo a2dismod php5 > ``
我们将为mod_fastcgi
添加一个配置块,这取决于mod_action
。
1sudo a2enmod actions
找出在您的 Droplet 上安装了哪些版本的 Apache:
1sudo apache2 -v
相应地编辑fastcgi
配置文件,这些配置指令将对.php
文件的请求传送到PHP5-FPM UNIX插槽。
1sudo nano /etc/apache2/mods-enabled/fastcgi.conf
将下列行添加到IfModule mod_fastcgi.c>... </IfModule>
块的底部为Apache 2.4**
:
1AddType application/x-httpd-fastphp5 .php
2 Action application/x-httpd-fastphp5 /php5-fcgi
3 Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
4 FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization
5 <Directory /usr/lib/cgi-bin>
6 Require all granted
7 </Directory>
Apache 2.2 不需要<目录>
部分,所以添加以下内容:
1AddType application/x-httpd-fastphp5 .php
2 Action application/x-httpd-fastphp5 /php5-fcgi
3 Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
4 FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization
在「fastcgi.conf」中完成后,进行配置测试。
1sudo apachectl -t
如果您看到警告无法使用 127.0.1.1 可靠地确定服务器的完全合格域名
,则将ServerName
指令设置在全球范围内以抑制此消息,这没问题。
1sudo service apache2 reload
第4步:验证PHP功能
检查PHP是否通过创建一个phpinfo()
文件并从您的Web浏览器访问它。
1echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php
要在浏览器中查看该文件,请访问 http://111.111.111.111.111:8080/info.php,但使用您的 Droplet 的 IP 地址。
在页面顶部,检查 Server API 说** FPM/FastCGI** . 页面下方约三分之二的路径,** PHP变量** 部分会告诉你** SERVER_SOFTWARE** 是Ubuntu上的Apache. 这些证实mod_fastcgi
是活跃的,而Apache正在使用PHP5-FPM来处理PHP文件。
第5步:为Apache创建虚拟主机
我们将为域名foobar.net
和test.io
创建两个Apache虚拟主机文件,这开始于为两个网站创建 _document root_目录。
1sudo mkdir -v /var/www/{foobar.net,test.io}
现在,我们将在安装完成后将两个文件添加到每个目录中进行测试。
首先,我们将为每个网站创建一个索引
文件。
1echo "<h1 style='color: green;'>Foo Bar</h1>" | sudo tee /var/www/foobar.net/index.html
1echo "<h1 style='color: red;'>Test IO</h1>" | sudo tee /var/www/test.io/index.html
然后,一个phpinfo()
文件。
1echo "<?php phpinfo(); ?>" | sudo tee /var/www/foobar.net/info.php
1echo "<?php phpinfo(); ?>" | sudo tee /var/www/test.io/info.php
创建foobar.net
域名的虚拟主机文件。
1sudo nano /etc/apache2/sites-available/foobar.net.conf
将下列指令纳入其中:
1<VirtualHost *:*>
2 ServerName foobar.net
3 ServerAlias www.foobar.net
4 DocumentRoot /var/www/foobar.net
5 <Directory /var/www/foobar.net>
6 AllowOverride All
7 </Directory>
8</VirtualHost>
保存并关闭文件. 然后对 test.io
做同样的事情。
1sudo nano /etc/apache2/sites-available/test.io.conf
1<VirtualHost *:*>
2 ServerName test.io
3 ServerAlias www.test.io
4 DocumentRoot /var/www/test.io
5 <Directory /var/www/test.io>
6 AllowOverride All
7 </Directory>
8</VirtualHost>
注1: AllowOverride All
启用了.htaccess
支持。
注2: 这些只是最基本的指南. 有关在 Apache 中设置虚拟主机的完整指南,请参阅 如何在 Ubuntu 14.04 LTS 上设置 Apache 虚拟主机。
现在两个Apache虚拟主机已设置,使用a2ensite
命令启用网站,从而在sites-enabled
目录中创建一个符号链接到虚拟主机文件。
1sudo a2ensite foobar.net
1sudo a2ensite test.io
再次检查 Apache 对配置错误。
1sudo apachectl -t
重新加载,如果显示了 Syntax OK 。
1sudo service apache2 reload
要确认网站正在工作,请在浏览器中打开http://foobar.net:8080
和http://test.io:8080
并验证它们是否显示其 index.html 文件。
你应该看到:
此外,通过访问 info.php 文件来检查 PHP 是否正在工作: http://foobar.net:8080/info.php
和 http://test.io:8080/info.php
。
您应该在每个网站上看到相同的PHP配置规格列表,就像您在步骤1中看到的那样。
第6步:安装和配置 Nginx
在此步骤中,我们将安装 Nginx,并将域名) on Ubuntu 14.04 LTS](https://andsky.com/tech/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-14-04-lts)。
安装 Nginx。
1sudo apt-get install nginx
然后删除默认虚拟主机的 symlink。
1sudo rm /etc/nginx/sites-enabled/default
现在我们将为 Nginx 创建虚拟主机. 首先为两个网站创建 document root 目录:
1sudo mkdir -v /usr/share/nginx/{example.com,sample.org}
与Apache的虚拟主机一样,我们将在安装完成后再次创建)`文件进行测试。
1echo "<h1 style='color: green;'>Example.com</h1>" | sudo tee /usr/share/nginx/example.com/index.html
1echo "<h1 style='color: red;'>Sample.org</h1>" | sudo tee /usr/share/nginx/sample.org/index.html
1echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/example.com/info.php
1echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/sample.org/info.php
现在为域名example.com
创建一个虚拟主机文件。
1sudo nano /etc/nginx/sites-available/example.com
Nginx 将配置文件中的服务器 {... }
区域称为服务器块 **. 为主要虚拟主机, example.com 创建服务器块.
默认_服务器` 配置指令使其成为默认的虚拟主机,它处理不匹配任何其他虚拟主机的 HTTP 请求。
将以下内容粘贴到 example.com 文件中:
1server {
2 listen 80 default_server;
3
4 root /usr/share/nginx/example.com;
5 index index.php index.html index.htm;
6
7 server_name example.com www.example.com;
8 location / {
9 try_files $uri $uri/ /index.php;
10 }
11
12 location ~ \.php$ {
13 try_files $uri =404;
14 fastcgi_pass unix:/var/run/php5-fpm.sock;
15 fastcgi_index index.php;
16 include fastcgi_params;
17 }
18}
现在,为 Nginx 的第二个域名,‘sample.org’创建一个虚拟主机文件。
1sudo nano /etc/nginx/sites-available/sample.org
sample.org 的服务器块应该是这样的:
1server {
2 root /usr/share/nginx/sample.org;
3 index index.php index.html index.htm;
4
5 server_name sample.org www.sample.org;
6 location / {
7 try_files $uri $uri/ /index.php;
8 }
9
10 location ~ \.php$ {
11 try_files $uri =404;
12 fastcgi_pass unix:/var/run/php5-fpm.sock;
13 fastcgi_index index.php;
14 include fastcgi_params;
15 }
16}
保存和关闭文件. 然后通过创建网站启用
目录的象征链接来启用两个网站。
1sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
1sudo ln -s /etc/nginx/sites-available/sample.org /etc/nginx/sites-enabled/sample.org
使用 Nginx 配置测试:
1sudo service nginx configtest
然后重新加载 Nginx 如果显示了 OK 。
1sudo service nginx reload
现在,您可以在网页浏览器中访问您的 Nginx 虚拟主机的 phpinfo()
文件,通过 http://example.com/info.php
和 http://sample.org/info.php
。
SERVER_SOFTWARE
应该说** nginx** ,表示这些文件是由Nginx直接提供的。** DOCUMENT_ROOT
** 应该指向您在此步骤中早些时候为每个Nginx网站创建的目录。
在此时刻,我们已经安装了 Nginx 并创建了两个虚拟主机,接下来我们将设置一个额外的虚拟主机来为在 Apache 上托管的域名提供代理请求。
第7步:为Apache的虚拟主机配置 Nginx
在本节中,我们将创建一个额外的 Nginx 虚拟主机,在server_name
指令中使用多个域名。
创建一个新的 Nginx 虚拟主机文件:
1sudo nano /etc/nginx/sites-available/apache
添加下面的代码块. 这将指定两个Apache虚拟主机域的名称,并向Apache代理他们的请求. 请记住在proxy_pass
中使用公共IP地址。
1server {
2 listen 80;
3 server_name foobar.net www.foobar.net test.io www.test.io;
4
5 location / {
6 proxy_pass http://111.111.111.111:8080;
7 proxy_set_header Host $host;
8 proxy_set_header X-Real-IP $remote_addr;
9 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
10 proxy_set_header X-Forwarded-Proto $scheme;
11 }
12}
保存文件并通过创建象征链接启用这个新的虚拟主机。
1sudo ln -s /etc/nginx/sites-available/apache /etc/nginx/sites-enabled/apache
进行配置测试:
1sudo service nginx configtest
重新加载 Nginx 如果显示了 OK 。
1sudo service nginx reload
打开浏览器,在Apache的域名中访问http://foobar.net/info.php
。
变量 SERVER_SOFTWARE 和** DOCUMENT_ROOT** 应该确认这个请求是由 Apache 处理的. 变量** HTTP_X_REAL_IP** 和** HTTP_X_FORWARDED_FOR** 由 Nginx 添加,应该显示您在浏览器中访问 URL 的计算机的公共 IP 地址。
我们已经成功设置了 Nginx 来向 Apache 提供特定域的代理请求,下一步是将 Apache 配置为设置变量 REMOTE_ADDR
,仿佛它正在直接处理这些请求。
第8步:安装和配置mod_rpaf
在此步骤中,我们将安装一个名为 mod_rpaf 的Apache模块,该模块会根据反向代理提供的值重新编写** REMOTE_ADDR** 、** HTTPS** 和** HTTP_PORT** 的值。如果没有这个模块,一些PHP应用程序将需要代码更改,以便从代理程序后面无缝工作。
安装编译和构建模块所需的包:
1sudo apt-get install unzip build-essential apache2-threaded-dev
从GitHub下载最新稳定版本。
1wget https://github.com/gnif/mod_rpaf/archive/stable.zip
用它提取:
1unzip stable.zip
转到工作目录。
1cd mod_rpaf-stable
然后编译并安装模块。
1sudo make
1sudo make install
在mods-available
目录中创建一个文件,其中加载 rpaf 模块。
1sudo nano /etc/apache2/mods-available/rpaf.load
将以下行添加到文件中:
1LoadModule rpaf_module /usr/lib/apache2/modules/mod_rpaf.so
在此目录中创建另一个文件. 这将包含配置指令。
1sudo nano /etc/apache2/mods-available/rpaf.conf
添加以下代码块,确保添加您的Droplet的IP地址。
1<IfModule mod_rpaf.c>
2 RPAF_Enable On
3 RPAF_Header X-Real-Ip
4 RPAF_ProxyIPs 111.111.111.111
5 RPAF_SetHostName On
6 RPAF_SetHTTPS On
7 RPAF_SetPort On
8</IfModule>
请参阅)以获得更多信息。
RPAF_Header - 用于客户端真实 IP 地址的标题.* RPAF_ProxyIPs* - 调节 HTTP 请求的代理 IP.** RPAF_SetHostName* - 更新 vhost 名称以便 ServerName 和 ServerAlias 工作.** RPAF_SetHTTPS* - 根据 X-Forwarded-Proto
中包含的值设置 HTTPS
环境变量.** RPAF_SetPort* - 设置 SERVER_PORT
环境变量。
保存rpaf.conf
并启用该模块。
1sudo a2enmod rpaf
这将创建mods-enabled
目录中的rpaf.load
和rpaf.conf
文件的符号链接。
1sudo apachectl -t
如果返回了 Syntax OK ,请重新加载 Apache。
1sudo service apache2 reload
在您的浏览器上访问 Apache 网站的 phpinfo()
页面,并检查 PHP 变量 部分.** REMOTE_ADDR** 变量现在也将是您本地计算机的公共 IP 地址。
第9步:设置HTTPS网站(可选)
在此步骤中,我们将为在Apache上托管的两个域配置SSL证书。 Nginx支持SSL终止,因此我们可以设置SSL而不修改Apache的配置文件。
创建SSL证书及其私钥的目录。
1sudo mkdir /etc/nginx/ssl
对于本文,我们将使用自签名的SSL证书,有效期为10年,为foobar.net
和test.io
生成自签证书。
1sudo 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
1sudo 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
每次,您将被要求提供证书识别详细信息。
1Country Name (2 letter code) [AU]:US
2State or Province Name (full name) [Some-State]:New York
3Locality Name (eg, city) []:New York City
4Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean Inc
5Organizational Unit Name (eg, section) []:
6Common Name (e.g. server FQDN or YOUR name) []:example.com
7Email Address []:
现在打开apache
虚拟主机文件,该文件向 Nginx 向 Apache 传输请求。
1sudo nano /etc/nginx/sites-available/apache
由于我们为每个域都有单独的证书和密钥,我们需要为每个域拥有单独的服务器 {... }
块,您应该删除当前的内容,完成后,您的apache
vhost 文件应该看起来像下面。
1server {
2 listen 80;
3 listen 443 ssl;
4 server_name test.io www.test.io;
5
6 ssl on;
7 ssl_certificate /etc/nginx/ssl/test.io-cert.pem;
8 ssl_certificate_key /etc/nginx/ssl/test.io-key.pem;
9
10 location / {
11 proxy_pass http://111.111.111.111:8080;
12 proxy_set_header Host $host;
13 proxy_set_header X-Real-IP $remote_addr;
14 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
15 proxy_set_header X-Forwarded-Proto $scheme;
16 }
17}
18
19server {
20 listen 80;
21 listen 443 ssl;
22 server_name foobar.net www.foobar.net;
23
24 ssl on;
25 ssl_certificate /etc/nginx/ssl/foobar.net-cert.pem;
26 ssl_certificate_key /etc/nginx/ssl/foobar.net-key.pem;
27
28 location / {
29 proxy_pass http://111.111.111.111:8080;
30 proxy_set_header Host $host;
31 proxy_set_header X-Real-IP $remote_addr;
32 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
33 proxy_set_header X-Forwarded-Proto $scheme;
34 }
35}
保存文件并执行配置测试。
1sudo service nginx configtest
如果测试成功,重新加载 Nginx。
1sudo service nginx reload
通过浏览器访问 Apache 的一个域名,使用前缀 https://
: https://foobar.net/info.php
请参阅 PHP 变量 部分,变量** SERVER_PORT** 已设置为** 443** 和** HTTPS** 设置为** on** ,就好像 Apache 是通过 HTTPS 直接访问的。
步骤 10 — 阻止直接访问 Apache (可选)
由于Apache在公共IP地址上的端口8080
上倾听,所以它可以被所有人访问,可以通过在您的防火墙规则集中使用以下IPtables命令来阻止它。
1sudo iptables -I INPUT -p tcp --dport 8080 ! -s 111.111.111.111 -j REJECT --reject-with tcp-reset
请确保使用您的 Droplet 的 IP 地址,而不是红色示例。一旦您的防火墙封锁了端口 8080,请测试它是否无法访问 Apache. 打开您的 Web 浏览器并尝试在端口
80 上访问 Apache 的一个域名。
浏览器应该显示无法连接
或网页不可用
错误消息. IPtables的tcp-reset
选项可用,外部用户不会看到端口8080
和没有任何服务的端口之间的差异。
注: IPtables 规则无法默认地重新启动系统,有几种方法可以保存 IPtables 规则,但最简单的方法是在 Ubuntu 的存储库中使用iptables-persistent
。
步骤 11 — 使用 Nginx 服务静态文件(可选)
当 Nginx 代理人请求 Apache 域时,它会将每个文件请求发送到 Apache. Nginx 比 Apache 更快地服务静态文件,如图像、JavaScript 和风格表。
打开apache
虚拟主机文件。
1sudo nano /etc/nginx/sites-available/apache
添加两个额外的 location 块到每个服务器块,如下面的代码块中的红色显示。
1server {
2 listen 80;
3 server_name test.io www.test.io;
4 root /var/www/test.io;
5 index index.php index.htm index.html;
6
7 location / {
8 try_files $uri $uri/ /index.php;
9 }
10
11 location ~ \.php$ {
12 proxy_pass http://111.111.111.111:8080;
13 proxy_set_header Host $host;
14 proxy_set_header X-Real-IP $remote_addr;
15 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
16 proxy_set_header X-Forwarded-Proto $scheme;
17 }
18
19 location ~ /\. {
20 deny all;
21 }
22}
23
24server {
25 listen 80;
26 server_name foobar.net www.foobar.net;
27 root /var/www/foobar.net;
28 index index.php index.htm index.html;
29
30 location / {
31 try_files $uri $uri/ /index.php;
32 }
33
34 location ~ \.php$ {
35 proxy_pass http://111.111.111.111:8080;
36 proxy_set_header Host $host;
37 proxy_set_header X-Real-IP $remote_addr;
38 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
39 proxy_set_header X-Forwarded-Proto $scheme;
40 }
41
42 location ~ /\. {
43 deny all;
44 }
45}
「try_files」指令讓 Nginx 在 document root 中尋找檔案,並直接服務它們. 如果檔案有「.php」擴張,則將要求傳送到 Apache. 即使檔案在 document root 中找不到,也將要求傳送到 Apache,以便像 permalinks 這樣的應用程式功能無問題地工作。
备份文件并执行配置测试。
1sudo service nginx configtest
如果测试成功,重新加载 Nginx。
1sudo service nginx reload
要验证这是有效的,你可以检查Apache在/var/log/apache2
中的日志文件,并查看index.php
和foobar.net
的index.php
文件的GET请求。
警告: 包含位置 ~ /\.
指令非常重要,这会阻止 Nginx 打印.htaccess 和.htpasswd 等文件的内容。
结论
完成本教程后,你现在应该有一个 Ubuntu Droplet 与 Nginx 服务的example.com
和sample.org
,以及 Apache 服务的foobar.net
和test.io
。