基于 CentOS 7.9 分离部署 LAMP + NFS (测试环境)
服务器角色与 IP 规划(请根据实际修改)
| 角色 | 主机名 | IP 地址(示例) |
|---|---|---|
| NFS 服务器 | web-nfs | 11.11.11.6 |
| MySQL 服务器 | web-mysql | 11.11.11.5 |
| PHP-FPM 服务器 | web-php | 11.11.11.4 |
| Apache 服务器 | web-apache | 11.11.11.3 |
软件版本
Apache:2.4.67(源码编译)
PHP:8.2.0(源码编译,使用 Remi 源提供依赖)
MySQL:8.0.12(二进制包)
NFS:CentOS 7 自带的 nfs-utils
Discuz:X5.0
目录
1.1 关闭防火墙与 SELinux(简化方案,仅用于内网测试)
3.3 配置 my.cnf(限制监听 IP,仅允许 PHP 服务器连接)
4.5 修改 www.conf(监听所有 IP,并限制仅 Apache 可连接)
4.6 配置 systemd 服务并启动 PHP-FPM(实现开机自启)
4.7 (可选)防火墙放行 9000 端口(若未关闭防火墙)
5.2 编译安装 APR、APR-util 和 Apache 2.4.67
5.4 启用代理模块(用于转发 PHP 请求到 PHP-FPM)
5.5 配置虚拟主机(将 .php 请求转发给 PHP-FPM 服务器)
5.7 配置 Apache systemd 服务(开机自启与管理)
六. 挂载 NFS 共享目录(Apache 服务器 和 PHP 服务器)
七. 部署 Discuz 论坛(代码直接放入 NFS 共享目录)
7.2 将 upload 目录内容复制到 NFS 共享的站点目录
10.2 NFS exports 使用 root_squash 提升安全性
一. 所有服务器基础环境配置(四台均执行)
1.1 关闭防火墙与 SELinux(简化方案,仅用于内网测试)
systemctl stop firewalld
systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0
解释:生产环境建议按角色放行端口(见附录),此处为了快速搭建直接关闭
1.2 配置阿里源
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
1.3 安装基础依赖包和工具
yum -y install gcc gcc-c++ make \
pcre-devel openssl-devel expat-devel \
bzip2-devel libxml2-devel \
curl-devel libpng-devel libjpeg-devel freetype-devel \
unzip bzip2 wget sysstat numactl-libs libaio
注意:PHP 编译所需 libzip 将在 PHP 服务器上单独处理,CentOS 7 自带的 libzip 版本过低
二. NFS 服务器
目的:共享网站代码目录和备份目录,让 Apache 和 PHP 服务器实时访问同一份代码
2.1 安装 nfs-utils
yum -y install nfs-utils rpcbind
2.2 创建共享目录并设置初始权限
mkdir -pv /nfs_share/{www,backup}
chmod 755 /nfs_share/www
chmod 755 /nfs_share/backup
2.3 创建统一的 apache 用户
先检查是否已存在 apache 用户:
id apache
-
如果不存在,直接创建(id可以根据自己的实际情况来修改):
groupadd -g 48 apache useradd -r -M -u 48 -g 48 -s /sbin/nologin apache -
如果已存在但 UID/GID 不是 48/48,需要先删除或修改:
方法一:删除后重建(确保没有进程在使用该用户)userdel apache groupdel apache groupadd -g 48 apache useradd -r -u 48 -g 48 -M -s /sbin/nologin apache方法二:直接修改现有用户的 UID/GID:
groupmod -g 48 apache usermod -u 48 -g 48 apache # 修复文件属主(如果该用户之前拥有某些文件) find / -user 旧UID -exec chown -h 48 {} \; find / -group 旧GID -exec chgrp -h 48 {} \;
解释:NFS 基于 UID/GID 进行权限验证,必须保证所有机器上 apache 用户的 UID 和 GID 完全相同(48/48),否则会出现“无权限写入”的问题
参数释义:
- -r:创建系统用户,UID 落在系统用户段 (1~999),不能登录、无密码逻辑
- -M:不自动创建 /home/apache 家目录 apache 是服务账号,不需要登录目录
- -u 48: 指定用户 UID 固定 = 48(官方 httpd 默认 ID)
- -g 48: 前提:必须提前建好
groupadd -g 48 apache指定该用户的主 GID=48 - -s /sbin/nologin: 禁用 shell 登录,无法 ssh / 终端登陆服务器,安全
2.4 将共享目录属主改为 apache
chown -R apache:apache /nfs_share/www
chown -R apache:apache /nfs_share/backup
2.5 配置 exports 文件
cat > /etc/exports << EOF
# 网站目录:给 Apache(11.11.11.3) 和 PHP(11.11.11.4) 读写权限
/nfs_share/www 11.11.11.3(rw,sync,no_root_squash) 11.11.11.4(rw,sync,no_root_squash)
# 备份目录:三台机器均可写入
/nfs_share/backup 11.11.11.3(rw,sync,no_root_squash) 11.11.11.4(rw,sync,no_root_squash) 11.11.11.5(rw,sync,no_root_squash)
EOF
参数解释:
- rw:读写权限
- sync:同步写入,保证数据一致性
- no_root_squash:客户端root用户保留root权限,便于管理(生产环境建议修改为root_squash并配合文件系统权限控制)
2.6 启动 NFS 服务并设置开机自启
systemctl start rpcbind
systemctl enable rpcbind
systemctl start nfs-server
systemctl enable nfs-server
exportfs -rav # 重新加载 exports 配置

三. MySQL 服务器
3.1 下载并解压 MySQL 8.0.12
cd /usr/local/src/
tar xf mysql-8.0.12-el7-x86_64.tar.gz -C /usr/local/
mv /usr/local/mysql-8.0.12-el7-x86_64 /usr/local/mysql
3.2 创建 mysql 用户和数据目录
useradd -r -M -s /sbin/nologin mysql
mkdir -pv /data/mysql/mysql3306
chown -R mysql:mysql /data/mysql/mysql3306 /usr/local/mysql
chmod -R 755 /data/mysql/mysql3306
3.3 配置 my.cnf(限制监听 IP,仅允许 PHP 服务器连接)
cp /etc/my.cnf /etc/my.cnf.bak
cat > /etc/my.cnf << EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql/mysql3306
socket=/data/mysql/mysql3306/mysql3306.sock
user=mysql
port=3306
character-set-server=utf8mb4
default-storage-engine=INNODB
max_connections=1000
lower_case_table_names=1
# 监听本机 IP(不允许 0.0.0.0 全监听,提高安全性)
bind-address=11.11.11.5
[mysql]
socket=/data/mysql/mysql3306/mysql3306.sock
EOF
解释:bind-address=0.0.0.0 会监听所有网络接口,风险较高。改为具体 IP 后,再配合防火墙规则只放行 PHP 服务器 IP 访问 3306 端口
3.4 初始化数据库(记录临时密码)
/usr/local/mysql/bin/mysqld \
--initialize \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/data/mysql/mysql3306
# 输出末尾会显示临时密码
例如:A temporary password is generated for root@localhost: FjdPG>9,uDhH
3.5 配置启动脚本并启动 MySQL
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
# 修改启动脚本中的 basedir 和 datadir
sed -i '2i\basedir=/usr/local/mysql' /etc/init.d/mysqld
sed -i '3i\datadir=/data/mysql/mysql3306' /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig mysqld on
systemctl start mysqld
ss -tulanp | grep mysqld
3.6 登录并修改 root 密码,创建数据库及用户
使用初始化时生成的临时密码登录
/usr/local/mysql/bin/mysql -uroot -p'临时密码'
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root'; --生产环境建议使用强密码
CREATE DATABASE discuzdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'discuzu'@'11.11.11.4' IDENTIFIED BY '1';
GRANT ALL PRIVILEGES ON discuzdb.* TO 'discuzu'@'11.11.11.4';
FLUSH PRIVILEGES;
EXIT;
注意:生产环境请使用强密码。discuz只允许从 PHP 服务器 IP(11.11.11.4)连接
3.7 (可选)防火墙放行 MySQL 端口
若未关闭防火墙,执行:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="11.11.11.4" port protocol="tcp" port="3306" accept'
firewall-cmd --reload
四. PHP-FPM 服务器
4.1 创建统一的 apache 用户
操作同NFS
4.2 解决 libzip 依赖
添加 Remi 源获取新版 libzip (CentOS 7 默认 libzip 0.10,PHP 8.2 需要 >=1.3)
yum -y install epel-release yum-utils
yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum-config-manager --enable remi
yum -y install libzip5-devel
yum install -y sqlite-devel gmp-devel readline-devel libxslt-devel pkgconfig oniguruma oniguruma-devel
4.3 下载并编译 PHP 8.2.0
cd /usr/local/src/
# 如果文件已存在则跳过下载
tar -xf php-8.2.0.tar.bz2
cd php-8.2.0
./configure \
--prefix=/usr/local/php82 \
--with-config-file-path=/usr/local/php82/etc \
--enable-fpm \
--enable-opcache \
--with-fpm-user=apache \
--with-fpm-group=apache \
--with-openssl \
--with-curl \
--with-zlib \
--enable-gd \
--with-jpeg \
--with-freetype \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--enable-mbstring \
--enable-xml \
--enable-session \
--disable-rpath ;echo $?
make -j $(nproc) && make install ;echo $?
# 应返回 0
4.4 复制配置文件
cp -av php.ini-production /usr/local/php82/etc/php.ini
cd /usr/local/php82/etc/
cp -av php-fpm.conf.default /usr/local/php82/etc/php-fpm.conf
cp -av php-fpm.d/www.conf.default /usr/local/php82/etc/php-fpm.d/www.conf
4.5 修改 www.conf(监听所有 IP,并限制仅 Apache 可连接)
cat > /usr/local/php82/etc/php-fpm.d/www.conf << 'EOF'
[www]
user = apache
group = apache
listen = 0.0.0.0:9000
listen.owner = apache
listen.group = apache
# 关键:只允许 Apache 服务器 IP 连接
listen.allowed_clients = 11.11.11.3
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
EOF
解释:listen.allowed_clients 如果不设置,任何主机都能连接 9000 端口执行 PHP 代码,存在严重安全隐患。此处明确只放行 Apache 服务器的 IP。
4.6 配置 systemd 服务并启动 PHP-FPM(实现开机自启)
# 不配置systemd服务则用路径启动
/usr/local/php82/sbin/php-fpm -t # 检查语法是否有误,显示有test is successful则为成功
/usr/local/php82/sbin/php-fpm
cp /usr/local/src/php-8.2.0/sapi/fpm/php-fpm.service /etc/systemd/system/
/usr/local/php82/sbin/php-fpm -t
systemctl daemon-reload
systemctl enable php-fpm
systemctl start php-fpm
# 验证启动
ps aux | grep php-fpm
ss -tulanp | grep 9000
4.7 (可选)防火墙放行 9000 端口(若未关闭防火墙)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="11.11.11.3" port protocol="tcp" port="9000" accept'
firewall-cmd --reload
五. Apache 服务器
5.1 创建统一的 apache 用户
操作同NFS
5.2 编译安装 APR、APR-util 和 Apache 2.4.67
cd /usr/local/src/
# 解压(假设已有文件)
tar xf apr-1.7.6.tar.gz
tar xf apr-util-1.6.3.tar.gz
tar xf httpd-2.4.67.tar.bz2
cd apr-1.7.6
./configure --prefix=/usr/local/apr && make -j$(nproc) && make install ;echo $?
cd ../apr-util-1.6.3
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr && make -j$(nproc) && make install ;echo $?
cd ../httpd-2.4.67
./configure \
--prefix=/usr/local/apache \
--with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util \
--enable-so \
--enable-ssl \
--enable-cgi \
--enable-rewrite \
--enable-modules=most \
--enable-mpms-shared=all \
--with-pcre \
--with-zlib \
--with-mpm=event ;echo $?
make -j$(nproc) && make install ;echo $?
5.3 修改 Apache 用户和 ServerName
cp /usr/local/apache/conf/httpd.conf /usr/local/apache/conf/httpd.conf.bak
sed -i 's/^User daemon/User apache/' /usr/local/apache/conf/httpd.conf
sed -i 's/^Group daemon/Group apache/' /usr/local/apache/conf/httpd.conf
sed -i "s@#ServerName www.example.com:80@ServerName $(uname -n)@g" /usr/local/apache/conf/httpd.conf
5.4 启用代理模块(用于转发 PHP 请求到 PHP-FPM)
sed -i 's/^#LoadModule proxy_module/LoadModule proxy_module/' /usr/local/apache/conf/httpd.conf
sed -i 's/^#LoadModule proxy_fcgi_module/LoadModule proxy_fcgi_module/' /usr/local/apache/conf/httpd.conf
5.5 配置虚拟主机(将 .php 请求转发给 PHP-FPM 服务器)
cp -av /usr/local/apache/conf/extra/httpd-vhosts.conf /opt/httpd-vhosts.conf.bak.$(date +%Y-%m-%d_%H:%M:%S)
cat > /usr/local/apache/conf/extra/httpd-vhosts.conf << EOF
<VirtualHost *:80>
ServerName web1.Hanyj.com
DocumentRoot "/usr/local/apache/htdocs/web1.Hanyj.com"
DirectoryIndex index.php index.html
<Directory "/usr/local/apache/htdocs/web1.Hanyj.com">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:fcgi://11.11.11.4:9000"
</FilesMatch>
ErrorLog "logs/web1-error_log"
CustomLog "logs/web1-access_log" common
</VirtualHost>
EOF
解释:所有 .php 请求通过 mod_proxy_fcgi 转发给 PHP-FPM 服务器的 9000 端口。静态文件由 Apache 自身处理
5.6 主配置包含虚拟主机配置文件
sed -i 's@#Include conf/extra/httpd-vhosts.conf@Include conf/extra/httpd-vhosts.conf@g' /usr/local/apache/conf/httpd.conf
5.7 配置 Apache systemd 服务(开机自启与管理)
# 路径启动Apache
/usr/local/apache/bin/apachectl start
以下方式还未试验,wait a moment ๑ᵒᯅᵒ๑
cat > /etc/systemd/system/httpd.service << 'EOF'
[Unit]
Description=Apache HTTP Server
After=network.target remote-fs.target nfs-client.target
[Service]
Type=forking
ExecStart=/usr/local/apache/bin/apachectl start
ExecStop=/usr/local/apache/bin/apachectl stop
ExecReload=/usr/local/apache/bin/apachectl graceful
PIDFile=/usr/local/apache/logs/httpd.pid
PrivateTmp=true
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable httpd
systemctl start httpd
六. 挂载 NFS 共享目录(Apache 服务器 和 PHP 服务器)
注意:必须在部署 Discuz 之前完成挂载,因为 Discuz 代码将直接存放在 NFS 共享中。
6.1 Apache 服务器挂载 NFS
# 先确保没有本地文件残留(可选备份)
yum -y install nfs-utils
mount -t nfs 11.11.11.6:/nfs_share/www /usr/local/apache/htdocs/
echo "11.11.11.6:/nfs_share/www /usr/local/apache/htdocs nfs defaults,_netdev 0 0" >> /etc/fstab
# 挂载备份目录(可选,方便统一备份配置)
mkdir -pv /mnt/remote_backup
mount -t nfs 11.11.11.6:/nfs_share/backup /mnt/remote_backup
echo "11.11.11.6:/nfs_share/backup /mnt/remote_backup nfs defaults,_netdev 0 0" >> /etc/fstab
6.2 PHP 服务器挂载 NFS
yum -y install nfs-utils
mkdir -pv /usr/local/apache/htdocs # 若目录不存在则创建
mount -t nfs 11.11.11.6:/nfs_share/www /usr/local/apache/htdocs/
echo "11.11.11.6:/nfs_share/www /usr/local/apache/htdocs nfs defaults,_netdev 0 0" >> /etc/fstab
# 挂载备份目录(可选,方便统一备份配置)
mkdir -pv /mnt/remote_backup
mount -t nfs 11.11.11.6:/nfs_share/backup /mnt/remote_backup
echo "11.11.11.6:/nfs_share/backup /mnt/remote_backup nfs defaults,_netdev 0 0" >> /etc/fstab
6.3 MySQL 服务器挂载 NFS
yum -y install nfs-utils
mkdir -pv /backup
mount -t nfs 11.11.11.6:/nfs_share/backup /backup
echo "11.11.11.6:/nfs_share/backup /backup nfs defaults,_netdev 0 0" >> /etc/fstab
解释:挂载后,Apache 和 PHP 服务器的 /usr/local/apache/htdocs/ 目录实际指向 NFS 服务器上的 /nfs_share/www,两者看到的是完全相同的文件。后续只需在任意一台机器(或直接在 NFS 服务器)上操作代码即可。
七. 部署 Discuz 论坛(代码直接放入 NFS 共享目录)
执行位置:可以在 Apache 服务器、PHP 服务器或 NFS 服务器上,只要能够访问 NFS 共享目录即可。推荐在 NFS 服务器上操作,避免权限混乱。
7.1 解压 Discuz X5.0
cd /usr/local/src/
unzip Discuz_X5.0_20260510.zip # 假设已有该文件
7.2 将 upload 目录内容复制到 NFS 共享的站点目录
# 假设 NFS 共享挂载在 /nfs_share/www
cp -r /usr/local/src/upload/* /nfs_share/www/web1.Hanyj.com/
7.3 设置正确的权限和属主(在 NFS 服务器上执行)
chown -R apache:apache /nfs_share/www/web1.Hanyj.com
chmod -R 755 /nfs_share/www/web1.Hanyj.com
解释:因为 NFS 共享目录的属主是 apache,而 Apache 和 PHP 服务器上的 apache 也是相同的 UID/GID,所以它们可以正常读写
7.4 启动 Apache 并测试
/usr/local/apache/bin/apachectl start
# 检查虚拟主机是否加载
/usr/local/apache/bin/httpd -S | grep web1.Hanyj.com
八. 编辑本地hosts文件
8.1 以管理员身份运行记事本

8.2 编辑hosts文件

8.3 写入Apache的 IP 和设置的域名

九. 访问 Web 完成 Discuz 安装
打开浏览器访问 http://web1.Hanyj.com/install/或者访问Apache的ip:11.11.11.3
根据向导填写数据库信息:
-
数据库服务器:
11.11.11.5(MySQL IP) -
数据库名:
discuzdb -
数据库用户名:
discuzu -
数据库密码:
1 -
表前缀:默认
pre_
安装完成后,Discuz 会自动生成配置文件,并写入 NFS 共享目录,Apache 和 PHP 均可正常读取。





十. 附录:生产环境安全建议(可选)
10.1 按角色放行端口(替代完全关闭防火墙)
Apache 服务器(11.11.11.3):
firewall-cmd --permanent --add-service={http,https}
firewall-cmd --reload
PHP-FPM 服务器(11.11.11.4):
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="11.11.11.3" port protocol="tcp" port="9000" accept'
firewall-cmd --reload
MySQL 服务器(11.11.11.5):
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="11.11.11.4" port protocol="tcp" port="3306" accept'
firewall-cmd --reload
NFS 服务器(11.11.11.6):
firewall-cmd --permanent --add-service={rpc-bind,mountd,nfs}
firewall-cmd --reload
10.2 NFS exports 使用 root_squash 提升安全性
将 /etc/exports 中的 no_root_squash 改为 root_squash,并确保共享目录的权限由普通用户(apache)精确控制。
示例:
/nfs_share/www 11.11.11.3(rw,sync,root_squash) 11.11.11.4(rw,sync,root_squash)
10.3 MySQL 启用 SSL 连接(可选)
参考 MySQL 官方文档为 3306 端口配置 SSL 证书。
十一. 常见问题排查
后续完善
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐





所有评论(0)