部署LNMP环境

更新时间:
一键部署
我的部署

ECS实例上通过包管理器构建LNMP环境,支持 Alibaba Cloud Linux、CentOS 及 Ubuntu 多系统。采用手动部署方式,解决镜像环境难以定制配置文件的痛点,满足 WordPress、Magento 等动态网站对底层环境完全控制与安全加固的生产需求。

方案架构

image
  1. 用户的浏览器通过公网向ECS实例80端口发起HTTP请求。

  2. 作为Web服务器,Nginx负责接收并分发请求。如果是静态资源(如HTML、CSS、图片),直接读取并返回;如果是PHP脚本请求(如.php文件),则通过FastCGI协议将其转发给PHP-FPM处理。

  3. PHP-FPM(FastCGI Process Manager)接收并执行PHP代码。如果需要与数据库交互,会连接到MySQL数据库。

  4. MySQL负责存储和管理数据,执行PHP脚本发来的SQL查询,并将结果返回给PHP-FPM。

  5. PHP-FPM将执行结果生成HTML内容,返回给Nginx,最终由Nginx发送给用户的浏览器。

实施步骤

为保证流畅体验,建议ECS实例内存不低于2 GiB。

一、准备工作

配置公网IP与安全组以确保实例可被外部访问,并更新系统组件以修复潜在安全漏洞。

  1. 配置公网访问。

    确保ECS实例已分配公网IP或已绑定弹性公网IP(EIP),以允许公网访问。具体操作,请参见开通公网

  2. 添加安全组放行规则。

    ECS实例关联的安全组中添加入方向规则,放行 TCP 协议的 80 端口(用于HTTP访问)。具体操作,请参见添加安全组规则

  3. 更新系统及软件包。

    Alibaba Cloud Linux 3 / CentOS 8

    1. 登录ECS实例。

      1. 访问ECS控制台-实例。在页面左侧顶部,选择目标资源所在的资源组和地域。

      2. 进入目标实例详情页,单击远程连接,选择通过Workbench远程连接。根据页面提示登录,进入终端页面。

    2. 将系统已有的软件包列表和软件更新到最新版本。

      sudo dnf update -y

    Alibaba Cloud Linux 2 / CentOS 7

    1. 登录ECS实例。

      1. 访问ECS控制台-实例。在页面左侧顶部,选择目标资源所在的资源组和地域。

      2. 进入目标实例详情页,单击远程连接,选择通过Workbench远程连接。根据页面提示登录,进入终端页面。

    2. 更新系统及软件包至最新版本。

      sudo yum update -y

    Ubuntu

    1. 登录ECS实例。

      1. 访问ECS控制台-实例。在页面左侧顶部,选择目标资源所在的资源组和地域。

      2. 进入目标实例详情页,单击远程连接,选择通过Workbench远程连接。根据页面提示登录,进入终端页面。

    2. 更新系统及软件包至最新版本。

      sudo apt update -y && sudo apt upgrade -y

二、安装并配置Nginx

  1. 添加Nginx官方源并安装。

    Alibaba Cloud Linux 3 / CentOS 8

    #添加Nginx官方源
    sudo tee /etc/yum.repos.d/nginx.repo <<-'EOF'
    [nginx-stable]
    name=nginx stable repo
    baseurl=https://nginx.org/packages/centos/8/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    EOF
    
    #安装Nginx
    sudo dnf -y install nginx

    Alibaba Cloud Linux2 / CentOS 7

    # 添加Nginx官方源
    sudo tee /etc/yum.repos.d/nginx.repo <<-'EOF'
    [nginx-stable]
    name=nginx stable repo
    baseurl=https://nginx.org/packages/centos/7/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    EOF
    
    # 安装Nginx
    sudo yum -y install nginx

    Ubuntu

    # 安装Nginx依赖
    sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring
    
    # 导入Nginx官方签名密钥,以验证软件包来源的真实性
    curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
    
    # 设置NginxAPT仓库
    echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
    
    # 安装Nginx
    sudo apt update --debian 报错
    sudo apt install -y nginx
  2. 启动并设置开机自启。

    enable --now参数会同时完成启动服务和设置开机自启两个操作。
    sudo systemctl enable --now nginx
  3. 验证Nginx服务。
    执行curl http://127.0.0.1,如果终端输出了Nginx的欢迎页HTML代码,说明安装成功。

三、安装并加固MySQL

  1. 安装并启动MySQL。

    Alibaba Cloud Linux 3 / CentOS 8

    # Alibaba Cloud Linux 3 需要安装compat-openssl10以兼容旧版OpenSSL
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        if [ "$ID" = "alinux" ] && [ "$VERSION_ID" = "3" ]; then
            sudo yum install -y compat-openssl10
        fi
    fi
    
    # 添加MySQL 8.4YUM仓库
    sudo rpm -Uvh https://repo.mysql.com/mysql84-community-release-el8-1.noarch.rpm
    
    # 安装MySQL服务
    sudo dnf install -y mysql-server

    Alibaba Cloud Linux2 / CentOS 7

    # 添加MySQL 8.4仓库
    sudo rpm -Uvh https://repo.mysql.com/mysql84-community-release-el7-1.noarch.rpm
    
    # 安装MySQL服务
    sudo yum install -y mysql-server

    Ubuntu

    # Ubuntu默认源中包含MySQL,直接安装即可
    # Ubuntu 20.04及以上版本默认安装 MySQL 8.0
    # Ubuntu 18.04及以下版本默认安装 MySQL 5.x。
    sudo apt install -y mysql-server
  2. 启动并设置开机自启。

    Alibaba Cloud Linux / CentOS

    sudo systemctl enable --now mysqld

    Ubuntu

    sudo systemctl enable --now mysql
  3. 设置安全加固。

    MySQL默认配置存在安全风险(如允许匿名登录、允许root远程登录),需运行其自带的安全加固脚本。

    1. 获取初始root密码。

      仅适用于Alibaba Cloud Linux/CentOS(Ubuntu默认使用免密登录),获取的密码用于后续步骤重置密码。

      # 从日志中提取并显示临时密码
      sudo grep 'temporary password' /var/log/mysqld.log
    2. 运行加固脚本。

      执行命令 sudo mysql_secure_installation,并根据提示完成以下建议配置:

      1. 重置root账号密码:使用上一步获取的临时密码登录并设置新密码。

        建议设置一个包含大小写字母、数字和特殊符号,且长度不低于12位的强密码。
      2. 移除匿名用户:输入Y。

      3. 禁止root远程登录:输入Y。

      4. 删除测试库:输入 Y。

      5. 重载权限表:输入 Y。

四、安装并配置PHP

安装PHP、PHP-FPM(用于处理Web请求)以及连接MySQL的扩展组件。

  1. 添加PHP源并安装。

    Alibaba Cloud Linux 3 / CentOS 8

    # 添加PHP源
    cat > /etc/yum.repos.d/remi.repo << 'EOF'
    [remi]
    name=Remi\'s RPM Repository for Enterprise Linux 8 - x86_64
    baseurl=https://rpms.remirepo.net/enterprise/8/remi/x86_64/
    enabled=1
    gpgcheck=1
    gpgkey=https://rpms.remirepo.net/RPM-GPG-KEY-remi2024
    
    [remi-safe]
    name=Remi Safe Repository
    baseurl=https://rpms.remirepo.net/enterprise/8/safe/x86_64/
    enabled=1
    gpgcheck=1
    gpgkey=https://rpms.remirepo.net/RPM-GPG-KEY-remi2024
    EOF
    
    # 导入 GPG Key
    rpm --import https://rpms.remirepo.net/RPM-GPG-KEY-remi2024
    
    # 安装工具并启用模块
    dnf install -y yum-utils
    
    # 安装 PHP
    dnf install -y php php-fpm php-mysqlnd

    Alibaba Cloud Linux2 / CentOS 7

    # 安装Remi源
    sudo yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
    
    # 安装yum管理工具并启用PHP 8.2
    sudo yum install -y yum-utils
    sudo yum-config-manager --enable remi-php82
    
    # 安装PHP、PHP-FPMMySQL扩展
    sudo yum install -y php php-fpm php-mysqlnd

    Ubuntu

    # 安装PPA源管理工具
    sudo apt install -y software-properties-common
    
    # 添加ondrej/php PPA源
    sudo add-apt-repository -y ppa:ondrej/php
    
    # 安装PHP 8.2、PHP-FPMMySQL扩展
    sudo apt install -y php8.2 php8.2-fpm php8.2-mysql
  2. 启动并设置PHP-FPM开机自启。

    Alibaba Cloud Linux / CentOS

    sudo systemctl enable --now php-fpm

    Ubuntu

    sudo systemctl enable --now php8.2-fpm

五、配置Nginx支持PHP解析

默认情况下,Nginx 仅能处理静态网页(如 HTML、图片)。为支持动态网站(如WordPress),需配置Nginx.php文件的请求转发至PHP-FPM进行处理。否则,访问PHP页面时会出现文件被直接下载或无法显示的问题。

  1. 备份Nginx配置文件。

    sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
  2. 获取PHP服务的通信地址。

    Nginx通过该通信地址将PHP请求转发至PHP-FPM进行处理。

    Alibaba Cloud Linux / CentOS

    PHP_FPM_LISTEN=$(sudo sed -n 's/^\s*listen\s*=\s*//p' /etc/php-fpm.d/www.conf | head -n 1)
    echo "$PHP_FPM_LISTEN"

    Ubuntu

    PHP_FPM_LISTEN=$(sudo sed -n 's/^\s*listen\s*=\s*//p' /etc/php/8.2/fpm/pool.d/www.conf | head -n 1)
    echo "$PHP_FPM_LISTEN"
  3. 配置Nginx转发规则,将.php请求正确转发至PHP服务。

    根据上一步的输出结果,将下方命令中的 <PHP通信地址> 替换为实际的通信地址后执行:

    • 若输出为文件路径(如 /run/php-fpm/www.sock):使用的通信方式为Unix Socket(仅限本地通信,性能更好且更安全),PHP通信地址格式为unix:文件路径,例如 unix:/run/php-fpm/www.sock

    • 若输出为 IP:端口(如 127.0.0.1:9000):通信方式为TCP(支持跨主机通信,适用于PHP-FPMNginx分离部署的场景),可以直接作为PHP通信地址。

    sudo tee /etc/nginx/conf.d/default.conf <<-'EOF'
    server {
        listen       80;
        server_name  localhost;
        root /usr/share/nginx/html;
    
        # 设置默认首页文件
        index index.php index.html index.htm;
    
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    
        # 将.php请求转发给PHP-FPM
        location ~ \.php$ {
            fastcgi_pass   <PHP通信地址>;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
    EOF
  4. 检查配置文件。

    sudo nginx -t
    • 如果返回结果中包含关键字 successful,表示配置正确,可执行下一步。

    • 如果返回结果中包含 failed,表示配置错误。请检查命令中的路径是否替换正确,或执行以下命令从备份中恢复配置文件:

      sudo mv /etc/nginx/conf.d/default.conf.bak /etc/nginx/conf.d/default.conf
  5. 重启Nginx使配置生效。

    sudo systemctl restart nginx

六、验证LNMP环境

创建测试文件,验证Nginx能否解析PHP,以及PHP能否连接到MySQL数据库,以确保LNMP各组件协同工作正常。

  1. 验证Nginx解析。

    1. 创建测试文件:生成一个包含phpinfo() 函数的文件,用于输出当前PHP环境的详细配置。

      echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/html/phpinfo.php
    2. 浏览器验证:访问 http://<ECS公网IP>/phpinfo.php

      • 成功标志:页面正常渲染并展示PHP环境配置信息。

      • 失败标志:显示 "File not found" 或直接下载了文件。

    3. 清理测试文件:验证成功后,必须删除该文件phpinfo页面包含敏感信息,暴露于公网会带来安全风险。

  2. 验证PHPMySQL的连通性。

    创建一个PHP脚本,用于测试PHP能否通过mysqlnd扩展连接到数据库。

    1. 创建数据库和用户。
      使用root账户登录MySQL(输入步骤三中设置的root账号密码)。

      sudo mysql -u root -p

      在 mysql>提示符下执行以下命令,创建名为 webapp 的库和 webuser 用户,并授予其对该数据库的所有权限。

      CREATE DATABASE webapp;
      /* 将<YourPassword>替换为一个强密码。*/
      CREATE USER 'webuser'@'localhost' IDENTIFIED BY '<YourPassword>';
      GRANT ALL PRIVILEGES ON webapp.* TO 'webuser'@'localhost';
      FLUSH PRIVILEGES;
      EXIT;
    2. 创建数据库连接测试文件。
      将下面命令中的 <YourPassword> 替换为上一步设置的用户密码后再执行。

      sudo tee /usr/share/nginx/html/test.php <<-'EOF'
      <?php
      $servername = "localhost";
      $username = "webuser";
      $password = "<YourPassword>";
      $dbname = "webapp";
      // 创建连接
      $conn = new mysqli($servername, $username, $password, $dbname);
      // 检测连接
      if ($conn->connect_error) {
          die("数据库连接失败: " . $conn->connect_error);
      }
      echo "数据库连接成功!";
      ?>
      EOF
      • 浏览器验证:访问 http://<ECS公网IP>/test.php。当页面显示数据库连接成功!表示测试通过。

      • 清理测试文件:该脚本内包含明文的数据库账号密码,测试通过后必须立即删除,防止凭据泄露。

常见问题

浏览器访问超时或显示“无法访问此网站”

这通常是网络连接问题。请按以下顺序排查:

  1. 安全组:检查ECS实例的安全组入方向规则是否已放行80端口。

  2. 防火墙:检查操作系统内部的防火墙(如firewalldufw)是否关闭或已放行80端口。

  3. Nginx服务:执行sudo systemctl status nginx检查Nginx服务是否正在运行。如果未运行,查看日志sudo journalctl -xeu nginx寻找错误原因。

  4. 端口占用:检查80端口是否被其他程序占用。详细排查方法,请参见pingECS实例但端口不通的排查方法

浏览器显示“502 Bad Gateway”

此错误表示Nginx无法与PHP-FPM正常通信。

  1. PHP-FPM服务:执行sudo systemctl status php-fpm(或php8.2-fpm)检查服务是否运行。

  2. Socket路径:核对Nginx配置文件中fastcgi_pass指令的unix:后面的路径,是否与PHP-FPM配置文件中的listen路径完全一致。

  3. SELinux/AppArmor:在CentOS/Alibaba Cloud Linux上,可能是SELinux策略阻止了NginxPHP-FPM的通信。尝试执行sestatus查看状态,并检查/var/log/audit/audit.log中的拒绝日志。

  4. Socket权限:检查Socket文件的权限,确保Nginx的运行用户有权读写该文件。

如何允许MySQL远程访问?

默认配置下,MySQL禁止远程登录。如需开启,建议创建专用的远程用户,而不是直接开放root用户的远程访问权限。具体操作,请参见添加远程访问MySQL用户