引言
LEMP软件堆栈是一组可以用来服务动态网页和用PHP编写的网络应用程序的软件。这是一个缩写词,描述了一个Linux操作系统,一个Nginx(发音像“Engine-X”)Web服务器。后端数据存储在MySQL数据库中,动态处理由PHP处理。
本指南展示了如何在Ubuntu服务器上安装LEMP堆栈。Ubuntu操作系统负责堆栈中的Linux部分。我们将描述如何让其余组件运行起来。
前提条件
在开始本教程之前,需要一个已设置的Ubuntu服务器,具有非root用户,具有sudo
权限,并启用了防火墙以阻止非必要的端口。
设置完成后,以的非root用户身份登录并进行第一步。
建议使用至少有以下配置的服务器:
4 核心的 CPU,4GB 的内存
选择服务器提供商
为了本教程的演示,我将以一个具体的云服务提供商为例,展示如何进行操作。选择哪个提供商根据个人偏好和需求来决定。
以下步骤仅供参考,请根据实际需求选择配置。
购买云服务器
本示例中,我们选择了香港作为服务器区域。
点击 云产品 → 云服务器 → 立即购买
选择操作系统
在创建服务器实例时,选择 Ubuntu 作为操作系统。
连接到服务器
使用 X-shell 或偏好的 SSH 客户端,通过远程用户名和密码连接到服务器。成功连接后,将看到特定的欢迎信息,表明已成功登录。
第1步 - 安装Nginx Web服务器
为了向网站访问者展示网页,你将使用Nginx,这是一个高性能的Web服务器。你将使用APT包管理器来获取这个软件。
由于这是你本次会话中第一次使用apt
,请先更新服务器的包索引:
sudo apt update
之后,运行apt install
来安装Nginx:
sudo apt install nginx
当提示时,按Y
然后按ENTER
确认你想要安装Nginx。安装完成后,Nginx Web服务器将在你的Ubuntu服务器上活跃并运行。
如果你按照我们的初始服务器设置指南推荐启用了ufw
防火墙,你将需要允许连接到Nginx。Nginx在安装时注册了几个不同的UFW应用程序配置文件。要检查哪些UFW配置文件可用,运行:
sudo ufw app list
Output
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
推荐你启用最限制性的配置文件,但仍允许你需要的流量。由于你还没有在本指南中为你的服务器配置SSL,你只需要允许端口80
上的常规HTTP流量。
通过运行以下命令来启用:
sudo ufw allow 'Nginx HTTP'
你可以通过检查状态来验证更改:
sudo ufw status
此输出显示现在允许HTTP流量:
输出Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)
添加了新的防火墙规则后,你可以通过在Web浏览器中访问服务器的域名或公网IP地址来测试服务器是否运行。
如果你没有指向你服务器的域名,也不知道服务器的公网IP地址,你可以通过运行以下命令之一来找到它:
ip addr show
hostname -I
这将打印出一些IP地址。你可以尝试将它们逐一输入Web浏览器中。
或者,你可以检查哪个IP地址可以从互联网的其他位置访问:
curl -4 icanhazip.com
将你收到的地址写入Web浏览器,它将带你到Nginx的默认登录页面:
http://server_domain_or_IP
如果你收到这个页面,这意味着你已经成功安装了Nginx并为你的Web服务器启用了HTTP流量。
第2步 - 安装MySQL
现在你有了运行的Web服务器,你需要安装数据库系统来存储和管理你的网站数据。MySQL是在PHP环境中使用的流行的数据库管理系统。
再次使用apt
来获取并安装这个软件:
sudo apt install mysql-server
当提示时,按Y
确认安装,然后按ENTER
。
安装完成后,推荐你运行MySQL预安装的安全脚本。这个脚本将移除一些不安全的默认设置并锁定对你的数据库系统的访问。通过运行以下命令启动交互式脚本:
sudo mysql_secure_installation
你将被问及是否要配置VALIDATE PASSWORD PLUGIN
。
- *注意:**启用这个功能是一种判断。如果启用,不符合指定标准的密码将被MySQL拒绝。你可以安全地留空验证,但你应该始终使用强大、唯一的密码作为数据库凭证。
按Y
表示是,或按其他键继续不启用:
Output
VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?
Press y|Y for Yes, any other key for No:
如果你回答“是”,你将被要求选择密码验证级别。请记住,如果你输入2
作为最强级别,你将在尝试设置任何不包含数字、大小写字母和特殊字符的密码时收到错误:
Output
There are three levels of password validation policy:
LOW Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary file
Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 1
无论你选择是否设置VALIDATE PASSWORD PLUGIN
,你的服务器都会要求你为MySQLroot用户选择并确认一个密码。这与系统root不同。数据库root用户是一个具有完整权限管理数据库系统的管理员用户。尽管MySQL root用户的默认认证方法在设置密码时不使用密码,即使设置了密码,你也应该在这里定义一个强密码作为额外的安全措施。我们稍后会讨论这个问题。
如果你启用了密码验证,你将看到为你输入的root密码的密码强度,你的服务器会问你是否想继续使用该密码。如果你对你当前的密码满意,在提示时按Y
为“是”:
Output
Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
对于其余的问题,按Y
并按ENTER
键。这将移除一些匿名用户和测试数据库,禁用远程root登录,并加载这些新规则,以便MySQL立即尊重你所做的更改。
完成后,测试你是否能够登录到MySQL控制台:
sudo mysql
这将以管理数据库用户root连接到MySQL服务器,这是通过运行此命令时使用sudo
推断出来的。你应该收到以下输出:
Output
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.28-0ubuntu4 (Ubuntu)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
要退出MySQL控制台,写入以下内容:
exit
请注意,即使你在运行mysql_secure_installation
脚本时定义了一个密码,你也不需要作为root用户连接,即使设置了密码。这是因为,在Ubuntu上安装时,管理MySQL用户的默认认证方法是auth_socket
,而不是使用密码的方法。这乍一看可能像是一个安全问题,但它使数据库服务器更安全,因为只有具有sudo
权限的系统用户可以从控制台或具有相同权限的应用程序运行时登录为rootMySQL用户。实际上,这意味着你将无法使用管理数据库root用户从你的PHP应用程序连接。
为了提高安全性,最好为每个数据库设置具有较少权限的专用用户帐户,特别是如果你计划在服务器上托管多个数据库。
你的MySQL服务器现在已经安装并安全。接下来,你将安装PHP,LEMP堆栈的最后一个组件。
第3步 - 安装PHP
你已经安装了Nginx来提供你的内容,MySQL来存储和管理你的数据。现在你可以安装PHP来处理代码并为Web服务器生成动态内容。
虽然Apache在每个请求中嵌入PHP解释器,Nginx需要一个外部程序来处理PHP处理并作为PHP解释器本身和Web服务器之间的桥梁。这允许大多数基于PHP的网站有更好的整体性能,但它需要额外的配置。你需要安装php8.1-fpm
,它代表“PHP fastCGI进程管理器”,并使用当前版本的PHP(在撰写本文时),告诉Nginx将PHP请求传递给这个软件进行处理。此外,你还需要php-mysql
,一个PHP模块,允许PHP与基于MySQL的数据库通信。核心PHP包将作为依赖项自动安装。
要安装php8.1-fpm
和php-mysql
包,请运行:
sudo apt install php8.1-fpm php-mysql
当提示时,按Y
然后按ENTER
确认安装。
你现在已经安装了你的PHP组件。接下来,你将配置Nginx使用它们。
第4步 - 配置Nginx使用PHP处理器
当使用Nginx Web服务器时,我们可以创建_server blocks_(类似于Apache中的虚拟主机)来封装配置细节,并在单个服务器上托管多个域名。在本指南中,我们将使用your_domain作为示例域名。
在Ubuntu上,Nginx默认启用一个服务器块,并配置为从/var/www/html
目录提供文件。虽然这对于单个网站运作良好,但如果你要托管多个网站,管理起来可能会变得困难。我们不会修改/var/www/html
,而是在/var/www
中为your_domain网站创建一个目录结构,将/var/www/html
保留为默认目录,以便在客户端请求不匹配任何其他网站时提供服务。
按照以下方式为your_domain创建根Web目录:
sudo mkdir /var/www/your_domain
接下来,使用$USER
环境变量分配目录的所有权,它将引用你当前的系统用户:
sudo chown -R $USER:$USER /var/www/your_domain
然后,使用你喜欢的命令行编辑器在Nginx的sites-available
目录中打开一个新的配置文件。这里,我们将使用nano
:
sudo nano /etc/nginx/sites-available/your_domain
这将创建一个新的空白文件。插入以下基本配置:
/etc/nginx/sites-available/your_domain
server {
listen 80;
server_name your_domain www.your_domain;
root /var/www/your_domain;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \\.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
location ~ /\\.ht {
deny all;
}
}
通过从Nginx的sites-enabled
目录链接到配置文件来激活你的配置:
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
然后,从/sites-enabled/
目录中取消链接默认配置文件:
sudo unlink /etc/nginx/sites-enabled/default
注意:如果你需要恢复默认配置,你可以通过重新创建符号链接来做到这一点,如下所示:
sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
这将告诉Nginx在下次重新加载时使用配置。你可以通过运行以下命令来测试你的配置是否有语法错误:
sudo nginx -t
如果报告了任何错误,请回到你的配置文件中检查其内容,然后再继续。
当你准备好后,重新加载Nginx以应用更改:
sudo systemctl reload nginx
你的新网站现在活跃了,但Web根目录/var/www/your_domain
仍然为空。在该位置创建一个index.html
文件,以便你可以测试你的新服务器块是否按预期工作:
nano /var/www/your_domain/index.html
在此文件中包含以下内容:
<html>
<head>
<title>your_domain website</title>
</head>
<body>
<h1>Hello World!</h1>
<p>This is the landing page of <strong>your_domain</strong>.</p>
</body>
</html>
现在,使用你在服务器块配置文件中列出的域名或IP地址访问你的浏览器:
http://server_domain_or_IP
你将收到如下页面:
如果你收到这个页面,这意味着你的Nginx服务器块按预期工作。
你可以将这个文件保留作为你应用程序的临时登录页面,直到你设置一个index.php
文件来替换它。一旦你这样做了,记得从你的文档根目录中移除或重命名index.html
文件,因为它将默认优先于index.php
文件。
你的LEMP堆栈现在已完全配置。在下一步中,你将创建一个PHP脚本来测试Nginx实际上能够处理你的新配置网站中的.php
文件。
第5步 - 使用Nginx测试PHP
你的LEMP堆栈现在应该已经完全设置好了。你可以测试它来验证Nginx是否能够正确地将.php
文件交给你的PHP处理器。
你可以通过在你的文档根目录中创建一个测试PHP文件来做到这一点。使用你喜欢的文本编辑器打开一个名为info.php
的新文件:
nano /var/www/your_domain/info.php
将以下几行添加到新文件中。这是有效的PHP代码,将返回有关你的服务器的信息:
<?php
phpinfo();
完成后,保存并关闭文件。
你现在可以通过访问你在Nginx配置文件中设置的域名或公网IP地址,然后加上/info.php
来访问这个页面:
http://server_domain_or_IP/info.php
你将收到一个包含有关你的服务器的详细信息的网页
通过该页面检查了你的PHP服务器的相关信息后,最好删除你创建的文件,因为它包含了有关你的PHP环境和你的Ubuntu服务器的敏感信息。你可以使用rm
来删除该文件:
sudo rm /var/www/your_domain/info.php
你可以随时重新生成这个文件,如果你以后需要它。
第6步 - 从PHP测试数据库连接(可选)
如果你想测试PHP是否能够连接到MySQL并执行数据库查询,你可以创建一个带有虚拟数据的测试表,并从一个PHP脚本中查询其内容。在此之前,你需要创建一个测试数据库,并为它配置一个新的MySQL用户。
- *注意:**某些较旧版本的原生MySQL PHP库
mysqlnd
不支持caching_sha2_authentication
,这是MySQL 8的默认认证方法,你可能需要确保它们被配置为使用mysql_native_password
。
我们将创建一个名为example_database的数据库和一个名为example_user的用户,但你可以替换这些名称为不同的值。
首先,使用root账户连接到MySQL控制台:
sudo mysql
要从MySQL控制台创建一个新的数据库,请运行以下命令:
CREATE DATABASE example_database;
现在你可以创建一个新用户并授予他们对你创建的自定义数据库的完全权限。
以下命令创建了一个名为example_user
的新用户,使用mysql_native_password
作为默认认证方法。我们定义这个用户的密码为password
,但你应该用你自己选择的安全密码替换这个值。
CREATE USER 'example_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
现在我们需要给这个用户权限管理example_database
数据库:
GRANT ALL ON example_database.* TO 'example_user'@'%';
这将给example_user用户完全权限管理example_database数据库,同时防止这个用户创建或修改服务器上的其他数据库。
现在用以下命令退出MySQL shell:
exit
你可以通过再次使用自定义用户凭证登录到MySQL控制台来测试新用户是否具有适当的权限。注意这个命令中的-p
标志,它会提示你输入创建example_user用户时使用的密码:
mysql -u example_user -p
登录到MySQL控制台后,确认你有访问example_database数据库的权限:
SHOW DATABASES;
这将返回以下输出:
输出+--------------------+
| Database |
+--------------------+
| example_database |
| information_schema |
+--------------------+
2 rows in set (0.000 sec)
接下来,我们将创建一个名为todo_list的测试表。从MySQL控制台运行以下语句:
CREATE TABLE example_database.todo_list (
item_id INT AUTO_INCREMENT,
content VARCHAR(255),
PRIMARY KEY(item_id)
);
在测试表中插入一些内容。你可能会想重复执行下一个命令几次,使用不同的值:
INSERT INTO example_database.todo_list (content) VALUES ("My first important item");
要确认数据已成功保存到你的表中,运行:
SELECT * FROM example_database.todo_list;
你的输出应该如下所示:
输出+---------+--------------------------+
| item_id | content |
+---------+--------------------------+
| 1 | My first important item |
| 2 | My second important item |
| 3 | My third important item |
| 4 | and this one more thing |
+---------+--------------------------+
4 rows in set (0.000 sec)
确认你在测试表中有有效数据后,退出MySQL控制台:
exit
现在你可以创建一个PHP脚本,该脚本将连接到MySQL并查询todo_list
表的内容。在自定义Web根目录中使用你喜欢的编辑器创建一个新的PHP文件。我们将为此使用nano
:
nano /var/www/your_domain/todo_list.php
以下PHP脚本连接到MySQL数据库并查询todo_list
表的内容,以列表形式展示结果。如果数据库连接有问题,它将抛出一个异常。
将以下内容添加到你的todo_list.php
脚本中:
<?php
$user = "example_user";
$password = "password";
$database = "example_database";
$table = "todo_list";
try {
$db = new PDO("mysql:host=localhost;dbname=$database", $user, $password);
echo "<h2>TODO</h2><ol>";
foreach($db->query("SELECT content FROM $table") as $row) {
echo "<li>" . $row['content'] . "</li>";
}
echo "</ol>";
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
编辑完成后保存并关闭文件。
你现在可以通过访问你的网站的域名或公网IP地址,然后加上/todo_list.php
来访问这个页面:
http://server_domain_or_IP/todo_list.php
你应该收到如下页面,显示你插入到你的测试表中的内容:
这意味着你的PHP环境已准备好连接并与你的MySQL服务器交互。
结论
在本指南中,你构建了一个灵活的基础,用于服务PHP网站和应用程序给你的访问者,使用Nginx作为Web服务器和MySQL作为数据库系统。你也可以使用Apache Web服务器来做这件事,还可以使用Let’s Encrypt保护你的网站,它提供免费、可信的证书。