如何在UbuntuVPS上从ApacheWeb服务器迁移到Nginx
介绍
在启动和运行网站或应用程序时,您必须做出许多选择。 有时,您的需求会发生变化,新技术变得可行,或者您的用户群会意外膨胀。 无论出于何种原因,您可能考虑更改的应用程序堆栈组件之一是 Web 服务器。
尽管 Apache Web 服务器是目前世界上最流行的 Web 服务器,但 Nginx 正在迅速普及。 考虑到 Nginx 在使用少量资源的情况下表现出色,这不足为奇。 对于许多网站来说,迁移到 Nginx 会提高性能。
在本指南中,我们将讨论如何在 Ubuntu 12.04 VPS 上将网站从 Apache 迁移到 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 {
部分,添加一个监听指令来告诉 Nginx 监听端口 80 以外的端口(Apache 仍在使用该端口来服务请求)。 对于我们的教程,我们将使用端口 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.com ServerName your_site.com ServerAlias www.your_site.com DocumentRoot /var/www <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /var/www/> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all </Directory> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined Alias /doc/ "/usr/share/doc/" <Directory "/usr/share/doc/"> Options Indexes MultiViews FollowSymLinks AllowOverride None Order deny,allow Deny from all Allow 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; # We're deliberately leaving this as-is to avoid conflict at the moment 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 配置为拒绝访问我们目录中任何 .htaccess
或其他以 .ht
开头的文件。 这些是特定于 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
在 PHP 变量 部分,您应该看到 Nginx 列为“SERVER_SOFTWARE”变量:
实时转换您的 Nginx 站点
在完成 extensive 测试后,您可以尝试将您的站点从 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/ ## Search all sites in this directory
在您对更改了所有必要的端口感到满意后,您可以像这样重新启动这两个服务:
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
apache2 install apache2-mpm-prefork install apache2-utils install apache2.2-bin install apache2.2-common install libapache2-mod-auth-mysql install libapache2-mod-php5 install
然后,您可以使用 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 有一个类似的重写模块,但使用不同的语法。 不幸的是,在 Nginx 中重写 URL 超出了本指南的范围。
模块和外部配置的复杂性
要记住的另一件事是,您需要了解您启用的 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 服务器的反向代理 。 这种方法可以以一种强大的方式利用两个服务器的优势。