如何在 Ubuntu VPS 上从 Apache Web 服务器迁移到 Nginx
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
简介
在启动网站或应用程序时,您需要做出许多选择。有时,您的需求会发生变化,新技术变得可行,或者您的用户群会意外膨胀。无论您的原因是什么,您可能会考虑更改应用程序堆栈的组件之一,即 Web 服务器。
尽管 Apache Web 服务器目前是世界上最流行的 Web 服务器,但 Nginx 正以迅猛的速度获得市场份额。这并不令人意外,考虑到 Nginx 在使用少量资源的同时表现出色。对于许多网站来说,迁移到 Nginx 可以提高性能。
在本指南中,我们将讨论如何将网站从 Apache 迁移到 Ubuntu 12.04 VPS 上的 Nginx。我们将尽量保持建议的通用性,但会为您提供一些可能需要根据自己的目的进行调整的提示。
本指南假定您已经使用此教程安装了 LAMP(Linux、Apache、MySQL 和 PHP)堆栈。如果您在创建 droplet 时只是选择了一键 LAMP 映像,则您的服务器也将具有此配置。
安装 Nginx
我们要做的第一件事是安装新的服务器软件,这将使我们能够通过查看当前的 Apache 配置文件来配置新的服务器。
幸运的是,Nginx 默认情况下存在于 Ubuntu 仓库中。让我们现在安装它:
sudo apt-get update
sudo apt-get install nginx
在我们的用例中,一个非常重要的实现细节是,Nginx 将任何动态处理都转移到一个单独的进程。这使得 Nginx 保持精简和快速。它可以专注于其核心功能,而无需尝试通过模块添加 PHP 支持。相反,它只是将其转移到专为此目的构建的应用程序。
这一点是在此时提到的,是因为我们还需要安装一个 PHP 处理程序,以便处理 PHP 脚本。标准选择是 php5-fpm
,它与 Nginx 配合良好:
sudo apt-get install php5-fpm
您应该已经拥有了所有需要的软件来将您的站点切换到 Nginx。我们仍然需要配置我们的软件以模拟 Apache 运行的配置。
设置测试 Nginx 配置
由于我们当前正在运行 Apache,如果可能的话,我们希望独立于 Apache 配置我们的 Nginx 服务器,以便在过渡期间我们的站点仍然可以正常运行。
这只是在另一个端口上测试 Nginx,直到我们准备好巩固我们的更改。这样,我们可以同时运行两个服务器。
首先打开默认 Nginx 站点的配置文件:
sudo nano /etc/nginx/sites-available/default
在 server {
部分,添加一个 listen 指令,告诉 Nginx 监听除端口 80 以外的端口(Apache 仍在使用端口 80 来提供请求)。在我们的教程中,我们将使用端口 8000。
server {listen 8000;. . .. . .
保存并关闭文件。现在是时候进行抽查,看看我们是否可以访问我们的 Nginx 服务器。启动 Nginx 来测试:
sudo service nginx start
使用我们配置的端口号访问默认的 Nginx 配置。在浏览器中输入:
http://your_ip_or_domain:8000
您的 Apache 实例应该仍在默认端口 80 上运行。您也可以通过访问您的站点(末尾没有 :8000
,我们的示例只是提供默认的 Apache 页面。如果您已经配置了您的网站,那么这里将会是您的网站)来检查:
http://your_ip_or_domain
翻译您的 Apache 配置
现在您已经运行了两个服务器,您可以开始迁移和翻译您的 Apache 配置,以便在 Nginx 中使用。这必须手动完成,因此重要的是您了解 Nginx 的配置方式。
这项任务主要涉及编写 Nginx 服务器块,这类似于 Apache 虚拟服务器。Apache 将这些文件保存在 /etc/apache2/sites-available/
,而 Nginx 也遵循相同的做法,在 Ubuntu 上将其服务器块声明保存在 /etc/nginx/sites-available/
中。
对于每个虚拟服务器声明,您将创建一个服务器块。如果您查看您的 Apache 文件,您可能会发现类似于以下内容的虚拟主机:
<VirtualHost *:80>ServerAdmin webmaster@your_site.comServerName your_site.comServerAlias www.your_site.comDocumentRoot /var/www<Directory />Options FollowSymLinksAllowOverride None</Directory><Directory /var/www/>Options Indexes FollowSymLinks MultiViewsAllowOverride NoneOrder allow,denyallow from all</Directory>ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/<Directory "/usr/lib/cgi-bin">AllowOverride NoneOptions +ExecCGI -MultiViews +SymLinksIfOwnerMatchOrder allow,denyAllow from all</Directory>ErrorLog ${APACHE_LOG_DIR}/error.logLogLevel warnCustomLog ${APACHE_LOG_DIR}/access.log combinedAlias /doc/ "/usr/share/doc/"<Directory "/usr/share/doc/">Options Indexes MultiViews FollowSymLinksAllowOverride NoneOrder deny,allowDeny from allAllow from 127.0.0.0/255.0.0.0 ::1/128</Directory>
</VirtualHost>
我们可以开始使用此配置构建我们的 Nginx 服务器块。
在您的 /etc/nginx/sites-available/
目录中,打开我们之前编辑以声明 Nginx 端口的文件:
sudo nano /etc/nginx/sites-available/default
暂时忽略注释行,它应该看起来像这样:
server {listen 8000;root /usr/share/nginx/www;index index.html index.htm;server_name localhost;location / {try_files $uri $uri/ /index.html;}location /doc/ {alias /usr/share/doc/;autoindex on;allow 127.0.0.1;deny all;}
}
您应该已经开始看到一些似乎对应于我们的 Apache 配置的项目。一般来说,主要指令的翻译如下:
Apache Nginx
------ ------<VirtualHost *:80> server {listen 80;ServerName yoursite.com
ServerAlias www.yoursite.com server_name yoursite.com www.yoursite.com;DocumentRoot /path/to/root root /path/to/root;AllowOverride All (No Available Alternative)DirectoryIndex index.php index index.php;ErrorLog /path/to/log error_log /path/to/log error;CustomLog /path/to/log combined access_log /path/to/log main;Alias /url/ "/path/to/files" location /url/ {
<Directory "/path/to/files"> alias /path/to/files;
如果我们要创建一个模拟上述虚拟主机文件功能的服务器块,它可能看起来像这样:
server {listen 8000; # 我们故意保留此设置,以避免冲突root /var/www;server_name your_site.com www.your_site.com;location / {try_files $uri $uri/ /index.html;}location ~ \.php$ {fastcgi_split_path_info ^(.+\.php)(/.+)$;fastcgi_pass unix:/var/run/php5-fpm.sock;fastcgi_index index.php;include fastcgi_params;}location /doc/ {alias /usr/share/doc/;autoindex on;allow 127.0.0.1;deny all;}location ~/\.ht {deny all;}}
我们已经删除了一些项目,并添加了一些额外的行,我们应该解释一下。
首先,错误日志行已从配置中删除。这是因为它们已经在 /etc/nginx/nginx.conf
文件中定义。这为我们提供了一个默认值,我们将使用它。
我们还删除了 ServerAdmin
指令,因为 Nginx 不会将该信息嵌入其错误页面。
PHP 处理也有所改变。由于 PHP 在 Nginx 中是单独处理的,我们将这些文件传递给我们之前安装的 php-fpm
程序。这是通过一个套接字实现的(我们需要立即配置)。
文档部分已更改以反映 Nginx 文档。它在其他方面基本上是类似的。
最后,我们配置 Nginx 拒绝访问任何以 .ht
开头的 .htaccess
或其他文件。这些是 Apache 特定的配置文件,它们与 Nginx 不兼容。最好不要公开这些配置文件。
完成后保存并关闭文件。
我们必须重新启动我们的 Nginx 服务器,以便识别这些更改:
sudo service nginx restart
配置 PHP-FPM
现在我们已经大部分完成了 Nginx 配置,我们需要修改 php-fpm 配置以便使用我们指定的通道进行通信。
首先,我们应该修改 php.ini 文件,以便它不会以不安全的方式提供文件。
sudo nano /etc/php5/fpm/php.ini
我们需要修改的行将要求 PHP 服务于精确请求的文件,而不是猜测是否存在不完整的匹配。这可以防止 PHP 可能向正在探测 PHP 处理程序弱点的人提供或暴露敏感数据。
找到指定 cgi.fix_pathinfo
指令的行,并修改为:
cgi.fix_pathinfo=0
保存并退出该文件。
接下来,我们将更改 php-fpm 连接到服务器的方式。在编辑器中打开以下文件:
sudo nano /etc/php5/fpm/pool.d/www.conf
找到并修改 listen
指令,使其与我们在服务器块配置文件中设置的值匹配:
listen = /var/run/php5-fpm.sock
如果您在处理大量 PHP 请求时遇到问题,您可能需要回来增加可以同时生成的子进程数量。您需要更改的行是:
pm.max_children = Num_of_children
保存并关闭该文件。
现在,我们的 php-fpm 程序应该已经正确配置。我们需要重新启动它以使更改生效。
sudo service php5-fpm restart
再次重新启动 Nginx 也不会有问题:
sudo service nginx restart
测试您在根目录中拥有的任何 PHP 文件是否能够正常运行。您应该能够像在 Apache 中一样执行 PHP 文件。
如果我们访问在 Ubuntu LAMP 教程中创建的 info.php
文件,它应该呈现如下:
http://your_ip_or_domain:8000/info.php
!DigitalOcean Nginx PHP files
在 PHP Variables 部分,您应该看到 Nginx 被列为 “SERVER_SOFTWARE” 变量:
!DigitalOcean Nginx server software
迁移您的 Nginx 站点
在进行了广泛的测试之后,您可以尝试将您的站点从 Apache 无缝迁移到 Nginx。
这是可能的,因为这两个服务器在重新启动之前都不会实施更改。这使我们能够设置好一切,然后在一个瞬间切换。
实际上,我们唯一需要做的就是修改 Nginx 服务器块中的端口。现在打开该文件:
sudo nano /etc/nginx/sites-available/default
将端口更改回默认的端口 80。这将使其在重新启动后立即开始接受常规的 HTTP 流量。
server {# listen 8000;listen 80;. . .
保存并关闭该文件。
如果您只是将一些站点迁移到 Nginx 并继续从 Apache 提供一些内容,您需要禁用在端口 80 上提供请求的 Apache 虚拟服务器。这是必要的以避免冲突。如果这样做得不正确,Nginx 将无法启动,因为端口已被占用。
如果您计划继续运行 Apache,请检查以下文件和位置以查找端口 80 的使用情况:
/etc/apache2/ports.conf
/etc/apache2/apache2.conf
/etc/apache2/httpd.conf
/etc/apache2/sites-enabled/ ## 在该目录中搜索所有站点
在您确信已经更改了所有必要的端口后,您可以像这样重新启动两个服务:
sudo service apache2 reload && sudo service nginx reload
Apache 应该重新加载,释放端口 80。随后,Nginx 应该重新加载并开始接受该端口上的连接。如果一切顺利,您的站点现在应该由 Nginx 提供服务。
如果您不再打算使用 Apache 来提供站点的任何部分,您可以完全停止其 Web 进程:
sudo service apache2 stop && sudo service nginx reload
如果您不再使用 Apache,那么此时您可以卸载 Apache 文件。您可以通过输入以下命令轻松找到与 Apache 相关的文件:
dpkg --get-selections | grep apache
然后使用 apt-get 卸载它们。例如:
sudo apt-get remove apache2 apache2-mpm-prefork apache2-utils apache2.2-bin apache2.2-common libapache2-mod-auth-mysql libapache2-mod-php5
您还可以删除所有不再需要的依赖包:
sudo apt-get autoremove
迁移复杂性
在尝试切换到 Nginx 时,Apache 世界中有一些常见的事情可能会让您感到困惑。
重写转换和 .htaccess 文件
最基本的区别之一是 Nginx 不遵守目录覆盖。
Apache 使用 .htaccess
文件,结合在位置块中的 AllowOverride All
指令。这允许您在包含文件的目录中放置特定于目录的配置。
Nginx 不允许这些文件。如果配置错误,将配置与正在提供的文件放在一起可能会带来安全问题,并且很容易查看集中式配置文件而不意识到通过 .htaccess 文件进行了设置覆盖。
因此,您在活动 .htaccess 文件中列出的所有配置必须放置在服务器块配置的位置块中。这通常并不更复杂,但您必须像处理虚拟主机定义一样翻译这些规则。
在 .htaccess 文件中保留的常见内容是 Apache 的 mod_rewrite 模块的规则,该模块修改内容的访问 URL 以使其更用户友好。Nginx 有一个类似的重写模块,但使用不同的语法。不幸的是,在本指南的范围之外重写 URL 在 Nginx 中。
模块和外部配置复杂性
另一件需要牢记的事情是,您需要意识到已启用的 Apache 模块提供了哪些功能。
一个简单的例子是 dir
模块。启用后,您可以通过在虚拟主机文件中添加以下行来指定 Apache 将尝试作为目录索引提供的文件顺序:
DirectoryIndex index.html index.htm
此行将确定此虚拟主机的处理方式。但是,如果此行不存在,并且已启用 dir
模块,则提供的文件顺序将由此文件确定:
sudo nano /etc/apache2/mods-enabled/dir.conf
<IfModule mod_dir.c>DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm</IfModule>
提出这一点的目的是,您必须意识到模块或任何外部配置可能在幕后执行某些操作,而这些操作在 Nginx 中必须显式执行。
在此示例中,您可以通过将以下内容添加到服务器块中来指定 Nginx 中的目录索引顺序:
server {. . .index index.php index.html index.htm;. . .
这一点很重要。
如果您正在迁移复杂的站点配置,可能会有所帮助的一点是将所有单独获取的配置文件复制粘贴到一个单一的文件中,并系统地逐行翻译每一行。
这可能会让人头疼,但对于生产服务器来说,它可以节省您大量时间,以便找出导致您无法准确确定的奇怪行为的原因。
结论
从 Apache 迁移到 Nginx 的复杂性几乎完全取决于您特定配置的复杂性。Nginx 可以处理几乎任何 Apache 可以处理的事情,并且以更少的资源完成。这意味着您的站点可以顺利为更多用户提供服务。
虽然迁移对于所有站点都没有意义,而且 Apache 是一个很好的服务器,可以满足许多项目的需求,但您可能会在 Nginx 中看到性能提升或可扩展性增加。如果您仍需要 Apache,另一种选择是将 Nginx 用作 Apache 服务器的反向代理。这种方法可以强大地发挥两个服务器的优势。