前几天朋友问我要怎么搭一个论坛,说网上教程要么太老、要么只说一半,照着做总卡壳。我刚好最近又完整做了一遍LNMP环境下的论坛部署,从裸机到论坛能正常发帖回帖,整个过程踩了不少坑,也顺手把很多以前没细想的原理弄明白了。这篇就把整套流程摊开讲,从方案选型、环境初始化、Nginx和PHP整合、数据库配置,再到论坛程序安装和上线前调优,所有步骤都带上为什么这么做、参数为什么这么调,最后再列一份我实际遇到过的问题排查清单。不管你是第一次接触LNMP的新手,还是想把自己那台VPS利用起来的老手,照着这篇走,应该能少走几天的弯路。
1. 方案选型:为什么是LNMP,版本和程序怎么定
1.1 从一次论坛需求说起
先说需求本身。要搭建一个可用的论坛,本质上就是一个动态Web应用。用户要能注册登录、发帖回帖、上传附件,管理员要能删帖封号、管理板块。这些功能背后需要三样东西:一个能处理HTTP请求的Web服务器,一个能存储用户和帖子数据的数据库,一个能执行论坛程序逻辑的脚本解释器。三样加起来,就是Web开发里常说的“运行环境”。
LNMP是Linux + Nginx + MySQL(通常用MariaDB替代)+ PHP的组合。为什么在2024年还要用这套老组合搭论坛?因为它成熟、稳定、资料多,而且论坛程序大多是以PHP为核心开发的,这是最主流、最不折腾的路子。相比之下,LNMP中的Nginx负责静态文件和反向代理,PHP处理动态逻辑,MySQL存数据,职责非常清晰。
有些朋友会问,怎么不用LAMP(Apache)?或者干脆用宝塔面板一键装?我的看法是:如果你的服务器只有一台、内存还不大,LNMP比LAMP省资源得多,Nginx处理静态请求的并发能力强,高并发场景下优势明显。宝塔确实省事,但很多人用了面板之后反而对底层原理一无所知,出了问题只能干瞪眼。自己动手敲一遍命令,装坏了重来几次,很多概念自然就通了。
1.2 组件版本怎么定,锁定一套不出错
选版本这事,很多人会纠结,其实不用纠结,只要遵循一个原则:用系统官方源里能直接装到的最新稳定版。我这次用的是Rocky Linux 9(RHEL 9的社区再编译版),软件版本如下:
| 组件 | 版本 | 说明 |
|---|---|---|
| 操作系统 | Rocky Linux 9.x / CentOS Stream 9 | 生产环境稳定优先 |
| Web服务器 | Nginx 1.20+(EPEL源) | 1.24更佳,模块齐全 |
| 数据库 | MariaDB 10.5+ | MySQL的社区分支,兼容性好 |
| PHP | PHP 8.1(php-fpm) | 论坛程序要求的最低版本以上 |
| 论坛程序 | Discuz! X3.5 | 国内资料多,部署简单,功能完整 |
为什么不直接装MySQL?因为Rocky Linux的默认源里没有MySQL官方包,装起来要额外配源,而MariaDB是MySQL的分支,API和命令行完全兼容,论坛程序根本感知不到差异,直接用很省心。
PHP必须装8.0以上的版本,因为新版Discuz!已经放弃了对PHP 7.x以下版本的支持。PHP 8.1是目前兼容性和性能都比较平衡的版本,OPcache扩展也默认集成,跑论坛绰绰有余。
论坛程序我选Discuz! X3.5。市面上还有phpBB、Flarum、NodeBB,但Discuz!在国内的生态最成熟,插件和模板多,部署文档全,适合作为生产环境。而且它对服务器配置的要求不高,虚拟主机都能跑,放在LNMP上更是游刃有余。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境基础配置,先把地基打稳
2.1 系统初始化与软件源调整
拿到一台全新的服务器,第一件事不是急急忙忙装Nginx,而是把系统基础环境调好。我习惯按这个顺序来:
bash复制# 更新系统所有软件包
dnf update -y
# 安装基本工具
dnf install -y vim wget curl tar unzip git
# 设置主机名,方便后面区分
hostnamectl set-hostname forum-server
# 关闭SELinux(如果你不想跟它纠缠)
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0
SELinux要不要关?这是个老话题。我个人的建议是:在实验环境或者自己折腾的服务器上,直接关掉,免得后面出现各种诡异的权限问题(比如PHP写不了session目录、Nginx访问不了文件)。你想排查半天发现是SELinux的avc拒绝日志,心态容易崩。如果是企业生产环境,建议学习写SELinux策略,但这篇文章就不展开了。
接着配置EPEL和Remi源。EPEL里有Nginx,Remi里有新版本的PHP:
bash复制dnf install -y epel-release
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
dnf module reset php -y
dnf module enable php:remi-8.1 -y
注意这里用了dnf module的操作,是因为Rocky Linux 9默认的PHP版本是8.0,但Remi源可以提供更多选择。启用Remi的PHP 8.1模块后,后续install的就是8.1版本了。
防火墙放行:如果开启了firewalld,需要允许HTTP和HTTPS端口。
bash复制firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
注意:数据库端口3306千万不要直接暴露到公网,默认防火墙不放行是好事,保持不放行就好。
2.2 Nginx安装与基础优化
Nginx的安装非常简单:
bash复制dnf install -y nginx
systemctl start nginx
systemctl enable nginx
装完访问服务器IP,能看到Nginx默认欢迎页就成了。但默认配置只是能跑,离生产可用还很远。我拿到默认的nginx.conf后,会调整这几个关键参数:
nginx复制worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 1024;
use epoll;
}
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"';
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/javascript application/json application/javascript application/xml image/svg+xml;
}
worker_processes auto的意思是让Nginx按CPU核心数自动启动worker进程。worker_connections 1024表示每个worker能同时保持的连接数。这两项是Nginx并发能力的核心,如果你的服务器是2核2G,用auto和1024完全够了,不要盲目调大,连接数太大会吃满内存。
gzip压缩必须开,论坛页面以HTML、CSS、JS为主,压缩后传输体量能减少60%以上,对首屏加载速度的提升非常直接。
这里有一个很多人忽略的点:Nginx默认的server块会监听80端口并指向/usr/share/nginx/html,这个留着没关系,但后面我们实际的站点配置应该放在/etc/nginx/conf.d/目录下,管理更清晰,避免和默认配置冲突。
2.3 MariaDB安装与安全初始化
数据库我选的MariaDB,安装命令:
bash复制dnf install -y mariadb-server
systemctl start mariadb
systemctl enable mariadb
启动后先跑安全初始化脚本:
bash复制mysql_secure_installation
这个脚本会依次问:是否设置root密码、是否删除匿名用户、是否禁止root远程登录、是否删除test数据库、是否重新加载权限表。我建议全部选yes。尤其是“禁止root远程登录”和“删除匿名用户”这两项,是数据库安全的基础,一定别省。
脚本跑完之后,用root登录MySQL验证一下:
bash复制mysql -uroot -p
能看到MariaDB的欢迎信息就成了。到这里,LNMP三个核心组件里已经装好两个,但先别急着部署论坛,因为PHP才是连接Nginx和MySQL的桥梁,把PHP配置好,整个链条才能串起来。
3. PHP部署与Nginx整合,这才是LNMP的枢纽
3.1 PHP 8.1安装与PHP-FPM配置
PHP装哪些包,直接关系到论坛能跑什么功能。Discuz!需要的PHP扩展比较基础,但也比较全。我的安装命令:
bash复制dnf install -y php php-fpm php-mysqlnd php-gd php-xml php-mbstring php-json php-curl php-zip php-opcache php-intl php-bcmath
简单解释几个关键扩展的作用:php-mysqlnd是与MariaDB通信的驱动,php-gd是处理图片缩略图和水印必须的,php-mbstring负责中文字符集处理,php-curl用于论坛的远程请求功能(比如获取远程图片),php-opcache则是PHP的字节码缓存,能从底层提升PHP执行速度。
启动PHP-FPM:
bash复制systemctl start php-fpm
systemctl enable php-fpm
PHP-FPM的配置文件位于/etc/php-fpm.d/www.conf,这里是LNMP性能调优的关键地方。我通常会改这几项:
ini复制user = nginx
group = nginx
listen = /run/php-fpm/www.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8
pm.max_requests = 500
user和group改成nginx,是因为Nginx的worker进程以nginx用户运行,PHP-FPM也要用同一用户,否则后面会出现权限问题。listen我选用Unix Socket而不是TCP端口(127.0.0.1:9000),因为Unix Socket走内核直接通信,少一层TCP栈开销,在同机部署时可以提升一部分性能。用Socket的关键是确保Nginx进程和PHP-FPM进程对socket文件有读写权限,所以设置了listen.owner和listen.group都是nginx,mode为0660。
pm相关的参数是PHP-FPM进程管理器的核心:max_children决定了最多能同时处理多少个PHP请求,这个值不是越大越好,而是和内存挂钩。按一个PHP进程平均占60MB内存来估算,2G内存的服务器,留给PHP 1.2G,max_children设置在20左右比较合理。
3.2 让Nginx正确转发PHP请求
Nginx本身不执行PHP代码,它需要把以.php结尾的请求转发给PHP-FPM处理。在/etc/nginx/conf.d/forum.conf里写一个完整的server块:
nginx复制server {
listen 80;
server_name forum.example.com;
root /var/www/html/forum;
index index.php index.html;
access_log /var/log/nginx/forum_access.log main;
error_log /var/log/nginx/forum_error.log warn;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
expires 30d;
access_log off;
}
location ~ /\.(ht|git|svn) {
deny all;
}
}
逐个说重点:
root指向的是论坛程序的实际目录,我习惯放在/var/www/html/forum。index按顺序写,优先加载index.php。location / 里的try_files是让Nginx在文件不存在时把所有请求交给index.php处理,这对使用伪静态的论坛来说非常关键——用户访问forum.com/thread-123.html时,文件系统里并不存在这个路径,需要交给PHP脚本解析并路由到对应帖子。
location ~ .php$ 则是Nginx与PHP-FPM的握手点。fastcgi_pass要和你PHP-FPM的listen保持一致,我用的是unix socket路径。fastcgi_param SCRIPT_FILENAME是必须要有的参数,告诉PHP-FPM要执行的脚本路径。
后面的静态文件location里,expires 30d表示给静态资源设置30天浏览器缓存,论坛的logo、CSS、JS都是不怎么变动的文件,缓存之后用户再次访问会直接从本地读,减少大量请求。最后一段是安全防护,禁止访问.htaccess这类隐藏文件,阻止别人探测目录结构。
写完后测试Nginx配置:
bash复制nginx -t
systemctl reload nginx
3.3 测试页与常见错误
为了确认PHP已经能正常运行,写一个测试文件:
bash复制echo "<?php phpinfo(); ?>" > /var/www/html/forum/info.php
浏览器访问http://你的IP/forum/info.php,如果能看到PHP版本信息、配置详情,说明Nginx和PHP之间的链路已经通了。
如果这一步失败,最常见的错误是502 Bad Gateway。出现502,基本就是Nginx无法与PHP-FPM通信。排查顺序:先看PHP-FPM有没有在跑,再看socket路径是否一致,最后看权限。服务运行正常但权限不对,错误日志里通常会有“Permission denied”字样,那就把listen.mode调成0666试试——不建议生产环境这么干,但排查阶段可以快速定位。
再补充一个我之前踩过的坑:如果Nginx server块里的root路径写错,PHP测试页访问时会返回404而不是502。因为Nginx会先检查文件是否存在,文件不存在直接404,根本不会转发给PHP。这时候要在错误日志里看“open() ... failed (2: No such file or directory)”的提示,路径问题最好定位。
测试完,马上删掉info.php:
bash复制rm -f /var/www/html/forum/info.php
phpinfo页面会把PHP版本、配置路径、扩展列表全暴露出去,坏人拿到这些信息后就能针对性地找漏洞,上线前必须清理。
4. 论坛程序部署与初始化流程
4.1 下载论坛源码与文件权限
我这里用Discuz! X3.5做演示。去官网下载最新版,或者用git拉取官方仓库也行:
bash复制cd /tmp
wget -O discuz.zip "https://www.discuz.net/discuzx/Download/index/version/X3.5"
unzip discuz.zip -d discuz/
cp -r discuz/upload/* /var/www/html/forum/
解压之后,目录里会有这几个关键部分:
- upload/ —— 论坛程序主文件
- utility/ —— 工具脚本,比如数据库转换工具,用不上就不要放进站点目录
- readme/ —— 安装说明
部署完成后,最重要的就是目录权限。Discuz!官方文档里对权限有明确要求,我总结成下表:
| 路径/文件 | 权限要求 | 说明 |
|---|---|---|
| /var/www/html/forum | 目录755 | 所有者nginx,组nginx |
| config/ | 目录755(安装后可设644) | 含数据库配置文件,需防篡改 |
| data/ | 目录777(安装后可适当收紧) | 缓存、附件、日志写入 |
| uc_client、uc_server | 目录755 | 用户中心相关,要保持可写 |
| 所有.php文件 | 644 | 可读即可,不需要执行位 |
执行权限设置:
bash复制chown -R nginx:nginx /var/www/html/forum
find /var/www/html/forum -type d -exec chmod 755 {} \;
find /var/www/html/forum -type f -exec chmod 644 {} \;
chmod -R 777 /var/www/html/forum/data
chmod -R 777 /var/www/html/forum/uc_client/data
chmod -R 777 /var/www/html/forum/uc_server/data
为什么data目录要777?因为论坛程序运行时会动态地在data目录下创建缓存文件、会话记录和附件,这些操作需要写权限。有一种更安全的方式是把目录所有者改成nginx,然后设置755就够用,但有些虚拟主机环境对权限的处理方式不同,777在LNMP单机部署下最省心。
有个细节我补一下:很多教程会建议把文件所有者设为www:www,但我们的Nginx和PHP-FPM都统一用nginx用户运行,所以这里也用nginx。如果你之前PHP-FPM里配置了user=apache,那就得改成apache,保持一致才不会出现“Nginx能访问但PHP写入失败”的诡异问题。
4.2 创建数据库和授权用户
论坛程序需要一个数据库用户来操作数据。这里有个安全要点:绝对不要直接用root用户连接数据库。正确做法是创建一个专用账号,只授权它访问论坛的数据库。
mysql复制CREATE DATABASE discuz CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'forum_user'@'localhost' IDENTIFIED BY 'YourStrongPassword!2024';
GRANT ALL PRIVILEGES ON discuz.* TO 'forum_user'@'localhost';
FLUSH PRIVILEGES;
字符集统一用utf8mb4。很多老论坛还停留在utf8,但utf8在MySQL里最多存3字节,遇到emoji表情(4字节)就会报错。用utf8mb4一劳永逸,Discuz! X3.5默认就支持utf8mb4,建库时指定即可。
数据库名discuz、用户名forum_user、密码自己换一个强密码。创建完先验证一下用户能不能正常登录:
bash复制mysql -uforum_user -p -D discuz
能进去看到数据库就说明授权没问题。
4.3 浏览器端安装与配置细节
数据库准备好之后,打开浏览器访问http://你的IP/forum/install/。Discuz!的安装程序会自动检测环境,列出哪些目录权限有问题,哪些PHP扩展缺失,照着提示改就行。
安装过程中要填数据库信息,这里有个容易填错的地方:数据库服务器地址,如果数据库和Web在同一台机器上,建议填localhost而不是127.0.0.1。填localhost时PHP会通过Unix Socket连接数据库,而填127.0.0.1会走TCP连接。两者都能用,但Socket连接更快,也更符合我们前面用Unix Socket的思路。
安装完成后,务必做两件事:
第一,删除安装目录,否则别人可以通过install目录重新安装,覆盖掉你的站点:
bash复制rm -rf /var/www/html/forum/install/
第二,把config目录权限收紧:
bash复制chmod -R 644 /var/www/html/forum/config
config目录里存着数据库账号密码,如果权限太宽,别人通过Web访问到config文件就能直接拖库。644权限只允许文件所有者写,其他人只能读。
到这里,论坛已经可以访问了。用管理员账号登录后台,你会发现功能极其丰富:板块管理、用户组、插件中心、模板风格、SEO设置……但这些先动都不急,先做上线前的检查。
5. 上线前检查与性能调优,让论坛真正能扛
5.1 关键安全设置,别让论坛裸奔
Discuz!后台有相当多安全选项,但以下几个是上线前必须处理的基础项:
管理员后台路径。Discuz!默认的后台路径是/admin.php,一眼就能被发现,暴力猜解的脚本满天飞。建议在后台全局设置里修改后台文件名,改成一串别人猜不到的名字,比如admin_ab12cd.php。这个操作能挡掉90%的扫描攻击。
开启验证码。注册页、登录页、发帖页都建议打开验证码。虽说验证码会影响用户体验,但没有任何防护的论坛会被灌水机器人刷到崩溃。Discuz!自带多种验证码方案,选一种不复杂的就行。
关闭注册后立即发帖的权限。新注册用户默认放在“等待验证”用户组,管理员审核通过后才能发帖,这个策略能有效防止广告机器人。
文件权限复查。把data目录从777收紧到755,目录所有者改为nginx。如果你的环境里Nginx和PHP-FPM都跑在nginx用户下,755就够了。如果之后发现论坛生成缓存或上传附件时出现“Permission denied”,再把特定子目录改回777即可。
还有一个容易忽略的安全项是Nginx的server_tokens。默认情况下Nginx会在响应头里带上版本号,比如“Server: nginx/1.24.0”,这等于告诉别人你的Nginx版本。在http块里加上server_tokens off,就能把版本信息隐藏掉。
5.2 PHP-FPM和MySQL调整,榨干2G内存
2G内存的机器,要在PHP和MySQL之间做平衡。我的思路是:PHP负责执行逻辑,需要快速响应;MySQL负责持久化,需要缓存数据。两边都调,但不能贪多。
PHP这边,除了前面说的pm参数,还有一个重要的地方是php.ini:
ini复制memory_limit = 256M
upload_max_filesize = 32M
post_max_size = 40M
max_execution_time = 60
date.timezone = Asia/Shanghai
memory_limit设置256M,是因为Discuz!在处理复杂页面(比如帖子列表带大量用户信息)时,PHP内存占用可能接近100M,再加上模板渲染,256M比较稳妥。upload_max_filesize是给论坛附件上传用的,如果你允许用户传大图,32M是起步值。
OPcache是PHP8自带的,确认一下配置:
ini复制opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
OPcache的作用是把PHP字节码缓存在内存里,第二次执行同一个PHP脚本时就不用重新解析。这对Discuz!这种页面多、脚本多的应用来说提升非常明显,实测能在CPU开销上降低一半以上。
MySQL这边,关键参数在/etc/my.cnf.d/下面,通常是一个server.cnf:
ini复制[mysqld]
innodb_buffer_pool_size = 512M
innodb_log_file_size = 64M
innodb_flush_log_at_trx_commit = 2
query_cache_type = 0
max_connections = 100
innodb_buffer_pool_size是InnoDB引擎的缓存池大小,官方建议设为物理内存的50%-70%。2G内存留512M给MySQL是因为还要同时跑Nginx和PHP,不能把内存全给MySQL。innodb_flush_log_at_trx_commit设为2表示每秒刷一次事务日志,可以在事务安全性可接受的情况下大幅提升写入性能,论坛这类应用场景完全够用。
max_connections设置为100就够。每个MySQL连接大约占5-10MB内存,100个连接占1G内存,别贪大。真出现连接数不够的情况,先排查是否有慢查询,而不是盲目调大。
调整完这些配置,记得重启让配置生效:
bash复制systemctl restart php-fpm
systemctl restart mariadb
5.3 静态资源加速与CDN思路
论坛页面上最影响加载速度的就是静态文件——CSS、JS、图片、字体。我们在Nginx配置里已经设置了30天缓存,但还可以更进一步。
Discuz!后台有“性能优化”选项,其中“CSS/JS缓存合并”功能非常实用:开启后论坛会把多个CSS合并成一个文件、多个JS合并成一个文件,减少HTTP请求数。一个页面从十几个请求降到三四个请求,加载速度提升立竿见影。
如果你的站有大量图片附件,可以考虑单独用一台对象存储或CDN来承载。Discuz!支持远程附件功能,可以把附件上传到云存储服务,让图片从CDN节点加载,大幅减轻源站压力。这个改动是在后台远程附件设置里配置,填上CDN域名和密钥即可。
我的建议是:1G内存的服务器就别开太多缓存功能,PHP-FPM保持均衡配置即可;2G内存可以做OPcache和静态文件缓存;如果流量真的起来了,先把附件搬到CDN,再考虑上Redis做内存缓存。
6. 常见问题与排查技巧实录
6.1 白屏、502和404,三步定位法
先给一个论坛部署阶段最常见的三类报错排查速查表,都是我自己实战用过来的经验:
| 现象 | 直接原因 | 排查路径 |
|---|---|---|
| 白屏(无任何输出) | PHP执行出错但错误被隐藏 | 查看/var/log/php-fpm/error.log,或临时在php.ini打开display_errors |
| 502 Bad Gateway | Nginx连不上PHP-FPM | 检查php-fpm进程、socket路径、selinux是否关闭 |
| 404 Not Found | Nginx找不到文件或伪静态规则没生效 | 检查root路径、fastcgi_param SCRIPT_FILENAME、.nginx rewrite规则 |
| 数据库连接失败 | 数据库账号密码/主机错误 | 用命令行mysql测试连接,逐项排除 |
踩坑实录:我最早部署Discuz!时遇到过白屏,页面完全是空的,不报任何错误。后来在php-fpm错误日志里看到了“PHP Fatal error: Uncaught Error: Call to undefined function curl_init()”,才发现是装PHP的时候漏了php-curl扩展。之后我养成了一个习惯:任何PHP应用部署前,先写一个phpinfo页,确认所有必需扩展都已经加载。
6.2 数据库连接失败,先分清是网络还是授权
Discuz!安装到“数据库连接失败”的提示,大多数情况是三个原因:
第一,数据库主机填法不对。如果填了服务器的公网IP,而MySQL只监听localhost,那必然会失败。用localhost连接是最稳的。检查MySQL监听状态:netstat -tlnp | grep 3306,如果看到监听地址是127.0.0.1,说明外部IP确实连不上。
第二,密码包含特殊字符导致解析问题。如果你在安装时填的数据库密码里有#、$、&等字符,论坛配置文件保存时可能被截断。遇到这种情况,最简单的办法是把密码改成字母加数字的组合,避免特殊字符。
第三,用户授权边界不对。我之前创建用户时用的是'forum_user'@'localhost',但PHP-FPM有时候会通过Socket文件连接,MySQL把它识别为主机名是localhost没问题。如果你看到“Access denied for user 'forum_user'@'localhost'”,先去MySQL里用这个账号手动登录一次,确认密码无误,再检查授权范围。
6.3 我踩过的一些坑,写给你避雷
坑一:防火墙把80端口挡了,自己在服务器本地访问没问题,换手机4G访问就超时。这个太常见了,检查firewall-cmd --list-all,确保http服务在放行列表里。
坑二:Nginx的root路径写成/var/www/html/forum/upload/forum,多了一层目录却浑然不知,导致页面下载了文件而不是显示HTML。这里提醒一下,部署目录要准确对应到upload目录里的文件,别把外层目录包进去了。
坑三:PHP-FPM的listen改成unix socket后,忘了改Nginx的fastcgi_pass,两边路径不一致,502卡了半天。检查fastcgi_pass和php-fpm的listen配置是否一致是很基础但也很容易忽略的一步。
坑四:改完Nginx配置没有reload,导致新配置没生效。改配置和重启服务是两件事,各自的语义不一样。Nginx用nginx -t测试配置,然后用systemctl reload nginx让新配置生效,reload是平滑重载,不会中断当前请求,我每次改完都要跑一遍。
坑五:数据库备份策略没做好,论坛崩了之后发现没有最近的备份,欲哭无泪。上线后我通常会写一个cron定时任务,每天凌晨用mysqldump备份数据库,保留最近七天的备份。下面这个脚本可以当模板:
bash复制#!/bin/bash
# 每日备份数据库
BK_DIR=/var/backups/mysql
DATE=$(date +%Y%m%d)
mkdir -p $BK_DIR
mysqldump -uroot -pYourPassword discuz | gzip > $BK_DIR/discuz_$DATE.sql.gz
find $BK_DIR -type f -mtime +7 -delete
然后加到crontab:
bash复制crontab -e
0 2 * * * /usr/local/bin/backup_forum.sh
数据库备份这事,配置简单,但养成的习惯价值无穷。另外,data/目录里的附件也可以定期打包备份,帖子可以重建,用户上传的图片丢了才是真损失。
最后再分享一个我个人的习惯:每次部署完一套环境,我会把所有改过的配置文件和命令整理成一份简单的部署文档,放在服务器/home目录下。下次系统崩了需要重装,照着这份文档重新执行一遍,半小时就能恢复,比翻聊天记录回忆当时做了什么靠谱得多。搭建LNMP环境从来不是一次性的工作,后续维护、更新、迁移都得靠这份沉淀下来的经验。
