本文提供从零开始在 CentOS 7/8 系统上部署 LEMP 环境(Linux + Nginx + MySQL + PHP)的完整教程,包含详细步骤和操作代码,适合零基础用户跟随操作。
环境准备与系统更新
在开始安装之前,确保系统是最新的并安装必要的工具。
步骤1:系统更新与基础工具安装
bash
# 切换到root用户
sudo su -
# 更新系统包(CentOS 7和8通用)
yum update -y
# 安装常用的工具和依赖
yum install -y wget curl vim git epel-release
# 对于CentOS 8,还需要启用PowerTools仓库
if [ -f /etc/redhat-release ] && grep -q "CentOS Linux release 8" /etc/redhat-release; then
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf config-manager --set-enabled powertools
fi
步骤2:禁用SELinux(可选但推荐)
bash
# 临时禁用SELinux
setenforce 0
# 永久禁用SELinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# 确认SELinux状态
sestatus
安装Nginx
步骤3:添加Nginx官方仓库并安装
bash
# 创建Nginx仓库配置文件
cat > /etc/yum.repos.d/nginx.repo << EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
# 安装Nginx
yum install -y nginx
# 启动Nginx并设置开机自启
systemctl start nginx
systemctl enable nginx
# 检查Nginx状态
systemctl status nginx
步骤4:配置防火墙
bash
# 检查防火墙状态(CentOS 7使用firewalld,CentOS 8默认也是firewalld)
systemctl status firewalld
# 开放HTTP和HTTPS端口
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
# 验证端口开放
firewall-cmd --list-all
安装MySQL
步骤5:安装MySQL 8.0
bash
# 下载并安装MySQL官方仓库
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
# 对于CentOS 8
if [ -f /etc/redhat-release ] && grep -q "CentOS Linux release 8" /etc/redhat-release; then
wget https://dev.mysql.com/get/mysql80-community-release-el8-3.noarch.rpm
fi
# 安装MySQL仓库
yum localinstall -y mysql80-community-release-*.rpm
# 安装MySQL服务器
yum install -y mysql-community-server
# 启动MySQL并设置开机自启
systemctl start mysqld
systemctl enable mysqld
# 检查MySQL状态
systemctl status mysqld
步骤6:MySQL安全配置
bash
# 获取临时root密码
grep 'temporary password' /var/log/mysqld.log
# 运行安全配置脚本(将使用上一步获取的临时密码)
mysql_secure_installation
# 按照提示完成以下安全设置:
# 1. 输入临时密码
# 2. 设置新密码(需包含大小写字母、数字和特殊字符)
# 3. 移除匿名用户
# 4. 禁止root远程登录
# 5. 移除test数据库
# 6. 重新加载权限表
步骤7:创建测试数据库和用户
bash
# 登录MySQL
mysql -u root -p
# 在MySQL中执行以下命令:
# 创建测试数据库
CREATE DATABASE testdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 创建专用用户
CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'YourSecurePassword123!';
# 授予权限
GRANT ALL PRIVILEGES ON testdb.* TO 'webuser'@'localhost';
# 刷新权限
FLUSH PRIVILEGES;
# 退出MySQL
EXIT;
安装PHP
步骤8:安装PHP及相关扩展
bash
# 对于CentOS 7,需要安装Remi仓库
if [ -f /etc/redhat-release ] && grep -q "CentOS Linux release 7" /etc/redhat-release; then
yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum-config-manager --enable remi-php74
fi
# 对于CentOS 8
if [ -f /etc/redhat-release ] && grep -q "CentOS Linux release 8" /etc/redhat-release; then
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpm
dnf module reset -y php
dnf module enable -y php:remi-7.4
fi
# 安装PHP和常用扩展
yum install -y php php-fpm php-mysqlnd php-json php-xml php-mbstring php-zip php-gd php-curl php-bcmath
# 启动PHP-FPM并设置开机自启
systemctl start php-fpm
systemctl enable php-fpm
# 检查PHP-FPM状态
systemctl status php-fpm
步骤9:配置PHP
bash
# 备份原始PHP配置文件
cp /etc/php.ini /etc/php.ini.backup
# 优化PHP配置(根据服务器配置调整)
sed -i 's/^;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php.ini
sed -i 's/^max_execution_time = 30/max_execution_time = 300/' /etc/php.ini
sed -i 's/^memory_limit = 128M/memory_limit = 256M/' /etc/php.ini
sed -i 's/^post_max_size = 8M/post_max_size = 100M/' /etc/php.ini
sed -i 's/^upload_max_filesize = 2M/upload_max_filesize = 100M/' /etc/php.ini
# 配置PHP-FPM池
cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.backup
# 重启PHP-FPM使配置生效
systemctl restart php-fpm
配置Nginx支持PHP
步骤10:配置Nginx虚拟主机
bash
# 创建网站目录
mkdir -p /var/www/html/example.com
chown -R nginx:nginx /var/www/html/example.com
chmod -R 755 /var/www/html
# 创建Nginx配置文件
cat > /etc/nginx/conf.d/example.com.conf << 'EOF'
server {
listen 80;
server_name example.com www.example.com;
root /var/www/html/example.com;
index index.php index.html index.htm;
access_log /var/log/nginx/example.com_access.log;
error_log /var/log/nginx/example.com_error.log;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# 安全增强
fastcgi_param HTTP_PROXY "";
fastcgi_hide_header X-Powered-By;
}
location ~ /\.ht {
deny all;
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public, immutable";
}
}
EOF
# 测试Nginx配置
nginx -t
# 重启Nginx
systemctl restart nginx
步骤11:创建测试PHP文件
bash
# 创建info.php测试文件
cat > /var/www/html/example.com/info.php << 'EOF'
<?php
phpinfo();
?>
EOF
# 创建数据库连接测试文件
cat > /var/www/html/example.com/dbtest.php << 'EOF'
<?php
$servername = "localhost";
$username = "webuser";
$password = "YourSecurePassword123!";
$dbname = "testdb";
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
echo "MySQL数据库连接成功!";
// 创建测试表
$sql = "CREATE TABLE IF NOT EXISTS test_table (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)";
if ($conn->query($sql) === TRUE) {
echo "<br>测试表创建成功";
} else {
echo "<br>创建表错误: " . $conn->error;
}
// 插入测试数据
$sql = "INSERT INTO test_table (firstname, email) VALUES ('测试用户', 'test@example.com')";
if ($conn->query($sql) === TRUE) {
echo "<br>测试数据插入成功";
} else {
echo "<br>插入数据错误: " . $conn->error;
}
// 查询数据
$sql = "SELECT id, firstname, email FROM test_table";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<br><br>查询结果:";
while($row = $result->fetch_assoc()) {
echo "<br> ID: " . $row["id"]. " - 姓名: " . $row["firstname"]. " - 邮箱: " . $row["email"];
}
} else {
echo "<br>0 结果";
}
$conn->close();
?>
EOF
# 设置正确的文件权限
chown nginx:nginx /var/www/html/example.com/*
chmod 644 /var/www/html/example.com/*.php
安全加固
步骤12:基本安全配置
bash
# 配置防火墙仅允许必要端口
firewall-cmd --permanent --remove-service=dhcpv6-client
firewall-cmd --permanent --add-port=22/tcp # SSH
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
# 禁用不必要的PHP函数
echo "disable_functions = exec,passthru,shell_exec,system,proc_open,popen,show_source" >> /etc/php.ini
# 配置PHP-FPM使用非特权用户
sed -i 's/^user = apache/user = nginx/' /etc/php-fpm.d/www.conf
sed -i 's/^group = apache/group = nginx/' /etc/php-fpm.d/www.conf
# 重启服务
systemctl restart php-fpm
systemctl restart nginx
测试环境
步骤13:验证安装
bash
# 检查所有服务状态
echo "=== Nginx状态 ==="
systemctl status nginx --no-pager -l
echo -e "\n=== MySQL状态 ==="
systemctl status mysqld --no-pager -l
echo -e "\n=== PHP-FPM状态 ==="
systemctl status php-fpm --no-pager -l
# 测试PHP版本
php -v
# 测试MySQL连接
mysql -u webuser -p -e "SHOW DATABASES;"
# 提示测试URL
echo -e "\n=== 测试URL ==="
SERVER_IP=$(curl -s ifconfig.me)
echo "PHP信息页面: http://$SERVER_IP/info.php"
echo "数据库测试: http://$SERVER_IP/dbtest.php"
部署实际项目
步骤14:部署简单的PHP应用
bash
# 创建项目目录结构
mkdir -p /var/www/html/example.com/{public,logs,config,uploads}
# 创建简单的PHP应用
cat > /var/www/html/example.com/public/index.php << 'EOF'
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LEMP环境测试应用</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; background: #f4f4f4; }
.container { max-width: 800px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
.status { padding: 10px; margin: 10px 0; border-radius: 4px; }
.success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
.info { background: #d1ecf1; color: #0c5460; border: 1px solid #bee5eb; }
</style>
</head>
<body>
<div class="container">
<h1>🎉 LEMP环境部署成功!</h1>
<div class="status info">
<h3>环境信息</h3>
<p><strong>服务器时间:</strong> <?php echo date('Y-m-d H:i:s'); ?></p>
<p><strong>PHP版本:</strong> <?php echo phpversion(); ?></p>
<p><strong>服务器软件:</strong> <?php echo $_SERVER['SERVER_SOFTWARE']; ?></p>
</div>
<?php
// 数据库连接测试
$db_config = [
'host' => 'localhost',
'user' => 'webuser',
'pass' => 'YourSecurePassword123!',
'name' => 'testdb'
];
$conn = new mysqli($db_config['host'], $db_config['user'], $db_config['pass'], $db_config['name']);
if ($conn->connect_error) {
echo '<div class="status error">';
echo '<h3>❌ 数据库连接失败</h3>';
echo '<p>错误: ' . $conn->connect_error . '</p>';
echo '</div>';
} else {
echo '<div class="status success">';
echo '<h3>✅ 数据库连接成功</h3>';
echo '<p>MySQL服务器版本: ' . $conn->server_info . '</p>';
// 测试查询
$result = $conn->query("SELECT COUNT(*) as count FROM test_table");
if ($result) {
$row = $result->fetch_assoc();
echo '<p>测试表记录数: ' . $row['count'] . '</p>';
}
$conn->close();
echo '</div>';
}
// PHP扩展检查
$required_extensions = ['mysqli', 'json', 'xml', 'mbstring', 'curl', 'gd'];
$missing_extensions = [];
foreach ($required_extensions as $ext) {
if (!extension_loaded($ext)) {
$missing_extensions[] = $ext;
}
}
if (empty($missing_extensions)) {
echo '<div class="status success">';
echo '<h3>✅ 所有必需PHP扩展已加载</h3>';
echo '</div>';
} else {
echo '<div class="status error">';
echo '<h3>❌ 缺少以下PHP扩展:</h3>';
echo '<p>' . implode(', ', $missing_extensions) . '</p>';
echo '</div>';
}
?>
<div class="status info">
<h3>下一步操作</h3>
<ul>
<li>删除测试文件 (info.php, dbtest.php)</li>
<li>配置域名和SSL证书</li>
<li>上传您的PHP应用程序</li>
<li>配置数据库和应用程序设置</li>
<li>设置定期备份</li>
</ul>
</div>
</div>
</body>
</html>
EOF
# 设置正确的权限
chown -R nginx:nginx /var/www/html/example.com
find /var/www/html/example.com -type d -exec chmod 755 {} \;
find /var/www/html/example.com -type f -exec chmod 644 {} \;
# 重启服务使更改生效
systemctl restart nginx
systemctl restart php-fpm
环境部署流程图
以下图表展示了完整的LEMP环境部署流程:
flowchart TD
A[开始部署LEMP环境] --> B[系统更新与准备]
B --> C[安装Nginx]
B --> D[安装MySQL]
B --> E[安装PHP]
C --> C1[Nginx配置]
D --> D1[MySQL安全配置]
E --> E1[PHP-FPM配置]
C1 --> F[服务集成配置]
D1 --> F
E1 --> F
F --> G[安全加固]
G --> H[测试验证]
H --> I{测试通过?}
I -->|是| J[部署应用]
I -->|否| K[故障排查]
K --> F
J --> L[环境优化]
L --> M[完成部署]
style A fill:#2c3e50,color:#fff
style M fill:#27ae60,color:#fff
style I fill:#e74c3c,color:#fff
style J fill:#3498db,color:#fff
故障排除
常见问题解决方案
bash
# 检查服务日志
journalctl -u nginx -f
journalctl -u php-fpm -f
journalctl -u mysqld -f
# 检查端口监听
netstat -tunlp | grep -E '(:80|:3306)'
# 检查文件权限
ls -la /var/www/html/example.com/
# 测试PHP处理
echo "<?php phpinfo(); ?>" | php
# 检查SELinux状态(如果启用)
getsebool -a | grep httpd
sesearch -A -s httpd_t -c file -p write
# 如果是SELinux问题,可以暂时设置为permissive模式
setenforce 0
性能优化建议
步骤15:基础性能优化
bash
# 配置Nginx性能参数
cat >> /etc/nginx/nginx.conf << 'EOF'
# 性能优化配置
server_tokens off;
client_max_body_size 100M;
keepalive_timeout 30;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
EOF
# 配置MySQL性能优化(根据服务器内存调整)
cat >> /etc/my.cnf << 'EOF'
# 基础性能优化
[mysqld]
innodb_buffer_pool_size = 256M
query_cache_size = 64M
query_cache_type = 1
max_connections = 100
slow_query_log = 1
slow_query_log_file = /var/log/mysql-slow.log
long_query_time = 2
EOF
# 重启服务
systemctl restart nginx
systemctl restart mysqld
总结
通过以上详细步骤,您已经成功在CentOS 7/8系统上部署了完整的LEMP环境。这个环境包含了:
- Nginx: 高性能Web服务器
- MySQL 8.0: 关系型数据库
- PHP 7.4: 服务器端脚本语言
- 必要的安全配置: 保护服务器安全
- 性能优化: 基础性能调优
现在可以开始部署PHP应用程序了。记得删除测试文件(info.php等)并配置您的域名和SSL证书以增强安全性。
如果在部署过程中遇到任何问题,请参考故障排除部分或检查相关服务日志。