Skip to content

在 AlmaLinux 10 上搭建 LEMP 环境

本教程将指导您在 AlmaLinux 10 上搭建完整的 LEMP(Linux, Nginx, MariaDB, PHP)Web 服务器环境。

教程概览

LEMP 技术栈组件

组件版本作用端口
LinuxAlmaLinux 10操作系统-
Nginx1.24+Web 服务器80, 443
MariaDB11.x数据库服务器3306
PHP8.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 应用。

基于 MIT 许可发布