在 AlmaLinux 10 上搭建 LEMP 环境
本教程将指导您在 AlmaLinux 10 上搭建完整的 LEMP(Linux, Nginx, MariaDB, PHP)Web 服务器环境。
教程概览
LEMP 技术栈组件
组件 | 版本 | 作用 | 端口 |
---|---|---|---|
Linux | AlmaLinux 10 | 操作系统 | - |
Nginx | 1.24+ | Web 服务器 | 80, 443 |
MariaDB | 11.x | 数据库服务器 | 3306 |
PHP | 8.3+ | 服务端脚本语言 | 9000 (PHP-FPM) |
预期结果
完成本教程后,您将拥有:
- 高性能的 Nginx Web 服务器
- 安全配置的 MariaDB 数据库
- 现代化的 PHP 8.3+ 运行环境
- SSL/TLS 证书支持
- 基本的安全加固配置
第一步:系统准备
1.1 系统更新
bash
# 更新系统包
sudo dnf update -y
# 安装必要的工具
sudo dnf install -y \
wget curl vim git \
firewalld policycoreutils-python-utils \
dnf-plugins-core
# 验证系统版本
cat /etc/almalinux-release
uname -a
1.2 配置防火墙
bash
# 启动并启用防火墙
sudo systemctl enable --now firewalld
# 开放 HTTP 和 HTTPS 端口
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=ssh
# 重新加载防火墙规则
sudo firewall-cmd --reload
# 验证配置
sudo firewall-cmd --list-all
1.3 配置 SELinux
bash
# 检查 SELinux 状态
sestatus
# 安装 SELinux 管理工具
sudo dnf install -y policycoreutils-python-utils
# 设置 SELinux 布尔值(允许 Web 服务器连接数据库)
sudo setsebool -P httpd_can_network_connect on
sudo setsebool -P httpd_can_network_connect_db on
第二步:安装 Nginx
2.1 安装 Nginx
bash
# 安装 Nginx
sudo dnf install -y nginx
# 启动并启用 Nginx
sudo systemctl enable --now nginx
# 检查服务状态
sudo systemctl status nginx
# 验证 Nginx 版本
nginx -v
2.2 配置 Nginx
bash
# 备份默认配置
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
# 创建优化的 Nginx 配置
sudo tee /etc/nginx/nginx.conf > /dev/null <<'EOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# 基本配置
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 64M;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
# 包含站点配置
include /etc/nginx/conf.d/*.conf;
}
EOF
# 验证配置语法
sudo nginx -t
2.3 创建默认站点
bash
# 创建网站根目录
sudo mkdir -p /var/www/html
# 创建默认站点配置
sudo tee /etc/nginx/conf.d/default.conf > /dev/null <<'EOF'
server {
listen 80;
listen [::]:80;
server_name _;
root /var/www/html;
index index.php index.html index.htm;
# 安全配置
server_tokens off;
# PHP 处理
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 静态文件处理
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 隐藏敏感文件
location ~ /\. {
deny all;
}
# 拒绝访问 PHP 配置文件
location ~ /(?:wp-config|config)\.php$ {
deny all;
}
}
EOF
# 重启 Nginx
sudo systemctl restart nginx
第三步:安装 MariaDB
3.1 安装 MariaDB 服务器
bash
# 安装 MariaDB
sudo dnf install -y mariadb-server mariadb
# 启动并启用 MariaDB
sudo systemctl enable --now mariadb
# 检查服务状态
sudo systemctl status mariadb
# 验证 MariaDB 版本
mysql --version
3.2 安全初始化
bash
# 运行安全安装脚本
sudo mysql_secure_installation
# 按照提示进行配置:
# 1. 当前 root 密码:直接回车(初始为空)
# 2. 设置 root 密码:Y
# 3. 输入新的 root 密码
# 4. 移除匿名用户:Y
# 5. 禁止 root 远程登录:Y
# 6. 移除测试数据库:Y
# 7. 重新加载权限表:Y
3.3 优化 MariaDB 配置
bash
# 创建自定义配置文件
sudo tee /etc/my.cnf.d/optimization.cnf > /dev/null <<'EOF'
[mysqld]
# 基本配置
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 性能优化
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
# 连接配置
max_connections = 100
connect_timeout = 10
wait_timeout = 600
max_allowed_packet = 64M
# 慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mariadb/slow.log
long_query_time = 2
# 二进制日志
log_bin = /var/log/mariadb/binlog
binlog_format = ROW
expire_logs_days = 7
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4
EOF
# 创建日志目录
sudo mkdir -p /var/log/mariadb
sudo chown mysql:mysql /var/log/mariadb
# 重启 MariaDB
sudo systemctl restart mariadb
3.4 创建测试数据库和用户
bash
# 连接到 MariaDB
mysql -u root -p
# 在 MySQL 提示符下执行:
sql
-- 创建测试数据库
CREATE DATABASE testsite CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建专用用户
CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'SecurePassword123!';
-- 授予权限
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON testsite.* TO 'webuser'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
-- 验证用户
SELECT User, Host FROM mysql.user WHERE User = 'webuser';
-- 退出
EXIT;
第四步:安装 PHP
4.1 安装 PHP 和扩展
bash
# 安装 PHP-FPM 和常用扩展
sudo dnf install -y \
php-fpm php-cli php-common \
php-mysql php-gd php-ldap \
php-odbc php-pear php-xml \
php-xmlrpc php-mbstring \
php-intl php-soap php-zip \
php-curl php-bcmath php-json \
php-opcache php-redis
# 验证 PHP 版本
php --version
php-fpm --version
4.2 配置 PHP-FPM
bash
# 备份默认配置
sudo cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.bak
# 编辑 PHP-FPM 池配置
sudo tee /etc/php-fpm.d/www.conf > /dev/null <<'EOF'
[www]
user = nginx
group = nginx
listen = 127.0.0.1:9000
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
slowlog = /var/log/php-fpm/www-slow.log
request_slowlog_timeout = 10s
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
security.limit_extensions = .php .php3 .php4 .php5 .php7
EOF
# 创建必要的目录
sudo mkdir -p /var/lib/php/session
sudo mkdir -p /var/lib/php/wsdlcache
sudo chown -R nginx:nginx /var/lib/php
4.3 优化 PHP 配置
bash
# 备份主配置文件
sudo cp /etc/php.ini /etc/php.ini.bak
# 修改重要的 PHP 配置
sudo sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php.ini
sudo sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 64M/' /etc/php.ini
sudo sed -i 's/post_max_size = 8M/post_max_size = 64M/' /etc/php.ini
sudo sed -i 's/max_execution_time = 30/max_execution_time = 300/' /etc/php.ini
sudo sed -i 's/memory_limit = 128M/memory_limit = 256M/' /etc/php.ini
sudo sed -i 's/;date.timezone =/date.timezone = Asia\/Shanghai/' /etc/php.ini
# 启用 OPcache
sudo tee /etc/php.d/10-opcache.ini > /dev/null <<'EOF'
; OPcache 配置
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
EOF
# 启动并启用 PHP-FPM
sudo systemctl enable --now php-fpm
# 检查服务状态
sudo systemctl status php-fpm
第五步:测试 LEMP 环境
5.1 创建 PHP 测试页面
bash
# 创建 PHP 信息页面
sudo tee /var/www/html/info.php > /dev/null <<'EOF'
<?php
phpinfo();
?>
EOF
# 创建数据库连接测试页面
sudo tee /var/www/html/dbtest.php > /dev/null <<'EOF'
<?php
$servername = "localhost";
$username = "webuser";
$password = "SecurePassword123!";
$dbname = "testsite";
try {
$pdo = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8mb4", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "<h2>数据库连接成功!</h2>";
echo "<p>服务器信息: " . $pdo->getAttribute(PDO::ATTR_SERVER_VERSION) . "</p>";
// 创建测试表
$sql = "CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)";
$pdo->exec($sql);
echo "<p>测试表创建成功</p>";
} catch(PDOException $e) {
echo "<h2>数据库连接失败: " . $e->getMessage() . "</h2>";
}
?>
EOF
# 创建简单的 HTML 首页
sudo tee /var/www/html/index.html > /dev/null <<'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;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 { color: #333; text-align: center; }
.status {
background: #e8f5e8;
padding: 15px;
border-radius: 5px;
margin: 10px 0;
border-left: 4px solid #4CAF50;
}
.links {
display: flex;
gap: 15px;
justify-content: center;
margin-top: 30px;
}
.links a {
background: #007cba;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 5px;
}
.links a:hover { background: #005a87; }
</style>
</head>
<body>
<div class="container">
<h1>🎉 LEMP 环境搭建成功!</h1>
<div class="status">
<h3>✅ 环境组件状态</h3>
<ul>
<li><strong>Linux:</strong> AlmaLinux 10</li>
<li><strong>Nginx:</strong> 运行中</li>
<li><strong>MariaDB:</strong> 运行中</li>
<li><strong>PHP:</strong> 运行中</li>
</ul>
</div>
<div class="links">
<a href="/info.php">PHP 信息</a>
<a href="/dbtest.php">数据库测试</a>
</div>
</div>
</body>
</html>
EOF
# 设置正确的文件权限
sudo chown -R nginx:nginx /var/www/html
sudo find /var/www/html -type f -exec chmod 644 {} \;
sudo find /var/www/html -type d -exec chmod 755 {} \;
# 设置 SELinux 上下文
sudo restorecon -Rv /var/www/html
5.2 验证服务状态
bash
# 检查所有服务状态
echo "=== 服务状态检查 ==="
sudo systemctl status nginx --no-pager -l
sudo systemctl status mariadb --no-pager -l
sudo systemctl status php-fpm --no-pager -l
# 检查端口监听
echo -e "\n=== 端口监听检查 ==="
sudo netstat -tlnp | grep -E ':80|:443|:3306|:9000'
# 测试 Web 服务器响应
echo -e "\n=== Web 服务器测试 ==="
curl -I http://localhost
5.3 浏览器访问测试
bash
# 获取服务器 IP 地址
ip addr show | grep 'inet ' | grep -v '127.0.0.1' | head -1
echo "请在浏览器中访问以下地址:"
echo "主页: http://your_server_ip/"
echo "PHP 信息: http://your_server_ip/info.php"
echo "数据库测试: http://your_server_ip/dbtest.php"
第六步:SSL/TLS 配置
6.1 安装 Let's Encrypt 证书
bash
# 安装 Certbot
sudo dnf install -y certbot python3-certbot-nginx
# 为域名申请证书(替换 yourdomain.com)
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# 设置自动续期
sudo crontab -e
# 添加以下行:
# 0 3 * * * /usr/bin/certbot renew --quiet
6.2 手动 SSL 配置(自签名证书用于测试)
bash
# 创建自签名证书
sudo mkdir -p /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/server.key \
-out /etc/nginx/ssl/server.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Test/CN=localhost"
# 更新 Nginx 配置支持 HTTPS
sudo tee /etc/nginx/conf.d/ssl.conf > /dev/null <<'EOF'
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name _;
root /var/www/html;
index index.php index.html;
# SSL 配置
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# 安全头
add_header Strict-Transport-Security "max-age=63072000" always;
# PHP 处理
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
# HTTP 重定向到 HTTPS
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://$server_name$request_uri;
}
EOF
# 重启 Nginx
sudo nginx -t && sudo systemctl restart nginx
第七步:性能优化和监控
7.1 系统性能监控
bash
# 安装监控工具
sudo dnf install -y htop iotop nethogs
# 创建性能监控脚本
sudo tee /usr/local/bin/lemp-status.sh > /dev/null <<'EOF'
#!/bin/bash
echo "=== LEMP 环境状态监控 ==="
echo "时间: $(date)"
echo ""
echo "=== 系统负载 ==="
uptime
echo -e "\n=== 内存使用 ==="
free -h
echo -e "\n=== 磁盘使用 ==="
df -h /
echo -e "\n=== 服务状态 ==="
systemctl is-active nginx mariadb php-fpm
echo -e "\n=== 进程数量 ==="
echo "Nginx: $(pgrep nginx | wc -l)"
echo "PHP-FPM: $(pgrep php-fpm | wc -l)"
echo "MariaDB: $(pgrep mariadb | wc -l)"
echo -e "\n=== 网络连接 ==="
ss -tuln | grep -E ':80|:443|:3306|:9000'
EOF
chmod +x /usr/local/bin/lemp-status.sh
# 运行监控脚本
/usr/local/bin/lemp-status.sh
7.2 日志管理
bash
# 配置日志轮转
sudo tee /etc/logrotate.d/lemp > /dev/null <<'EOF'
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 nginx nginx
sharedscripts
postrotate
systemctl reload nginx
endscript
}
/var/log/php-fpm/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 nginx nginx
sharedscripts
postrotate
systemctl reload php-fpm
endscript
}
EOF
故障排查
常见问题及解决方案
1. Nginx 502 Bad Gateway
bash
# 检查 PHP-FPM 状态
sudo systemctl status php-fpm
# 检查 PHP-FPM 日志
sudo tail -f /var/log/php-fpm/www-error.log
# 检查 SELinux 布尔值
sudo getsebool httpd_can_network_connect
# 如果为 off,启用它
sudo setsebool -P httpd_can_network_connect on
2. 数据库连接失败
bash
# 检查 MariaDB 状态
sudo systemctl status mariadb
# 测试数据库连接
mysql -u webuser -p -h localhost testsite
# 检查用户权限
mysql -u root -p -e "SELECT User, Host FROM mysql.user WHERE User='webuser';"
3. 文件权限问题
bash
# 重新设置权限
sudo chown -R nginx:nginx /var/www/html
sudo find /var/www/html -type f -exec chmod 644 {} \;
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo restorecon -Rv /var/www/html
安全加固建议
1. 隐藏服务器信息
bash
# 隐藏 Nginx 版本
sudo sed -i 's/# server_tokens off;/server_tokens off;/' /etc/nginx/nginx.conf
# 隐藏 PHP 版本
sudo sed -i 's/expose_php = On/expose_php = Off/' /etc/php.ini
2. 限制访问
bash
# 创建管理目录保护
sudo tee /etc/nginx/conf.d/admin-protection.conf > /dev/null <<'EOF'
location /admin {
allow 192.168.1.0/24; # 替换为您的 IP 段
deny all;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
EOF
3. 安装防护软件
bash
# 安装 Fail2ban
sudo dnf install -y fail2ban
# 启用 Fail2ban
sudo systemctl enable --now fail2ban
# 检查状态
sudo fail2ban-client status
验收清单
完成本教程后,请检查以下项目:
- [ ] Nginx 服务正常运行并响应 HTTP/HTTPS 请求
- [ ] MariaDB 服务正常运行并接受连接
- [ ] PHP-FPM 服务正常运行并处理 PHP 脚本
- [ ] 可以通过浏览器访问测试页面
- [ ] PHP 能成功连接数据库
- [ ] SSL/TLS 证书配置正确(如果启用)
- [ ] 防火墙规则配置正确
- [ ] 服务自启动配置完成
- [ ] 基本的安全加固措施已实施
🎉 恭喜!您已成功在 AlmaLinux 10 上搭建了完整的 LEMP 环境。
下一步:学习 云平台使用指南 了解如何在云环境中部署 LEMP 应用。