尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

LNMP环境搭建全攻略:从零部署Nginx、MySQL、PHP并上线Discuz论坛

LNMP环境搭建全攻略:从零部署Nginx、MySQL、PHP并上线Discuz论坛 1. 先说结论为什么是LNMP1.1 LNMP和LAMP的本质区别你可能会觉得奇怪搭论坛为什么非要用LNMP以前很多老教程都在讲LAMPLinux Apache MySQL PHPLNMP只是把Apache换成了Nginx。但真正跑过几年论坛的人应该都有感受Apache在处理高并发静态请求时内存占用和并发表现都不如Nginx直接。论坛这种应用页面大部分是动态生成的但图片、CSS、JS这类静态资源占比极高Nginx处理静态文件的效率比Apache好太多而且配置起来更清爽。我最早搭论坛用的是Apache后来一台2核4G的机器跑Discuz在线人数一多Apache进程瞬间把内存吃满机器直接卡死。换了Nginx之后同样配置的机器在线人数翻了一倍还能稳得住。这就是我后来一直推荐LNMP的原因它更适合PHP论坛这种“动态为主、静态也不少”的负载模型。另外LNMP还有一个隐藏优势Nginx的反向代理和负载均衡能力更强。如果你的论坛以后要拆分成图片服务器、API服务器Nginx可以很自然地做流量入口而Apache在这方面的配置要繁琐不少。所以哪怕你现在只需要搭一个小论坛从LNMP起步也是一个更省心的选择。1.2 跑论坛到底需要什么一个论坛系统的核心是用户发帖、回帖、搜索、权限管理。这些功能背后依赖的是三样东西Web服务器负责接收用户的HTTP请求让浏览器能访问到你的页面。数据库负责存储用户、帖子、版块、附件等结构化数据。脚本解释器负责执行PHP代码把动态内容从数据库里取出来渲染成网页。LNMP正好对应这三个角色各司其职。Nginx负责“接客”PHP-FPM负责“干活”MySQL负责“记东西”。三者之间通过FastCGI协议通信也就是Nginx收到请求后如果发现是PHP文件就把它交给PHP-FPM处理PHP-FPM再根据需要去读写MySQL。你还需要注意一点论坛程序的上传下载、头像裁剪、验证码生成等功能都依赖PHP的GD库、Fileinfo、OpenSSL等扩展。如果安装PHP时缺了扩展安装向导就会直接报错。所以后面我会特别强调PHP扩展的安装这一步踩坑的人特别多。2. 环境部署从零装出可用的LNMP2.1 系统与环境约定写这篇博文时我默认你用的是CentOS 7或Rocky Linux这类RHEL系系统这也是绝大多数云服务器厂商默认提供的系统。如果你用的是Ubuntu命令会有一些差异但思路完全一致。搭建前先确认三件事服务器内存至少1G推荐2G以上。PHP-FPM和MySQL都比较吃内存512M的小机器跑起来会很痛苦。系统盘和数据盘分开。论坛的附件、备份文件会越来越大建议把数据目录放到单独挂载的数据盘上。确认防火墙放行了80和443端口。很多人装好了环境发现访问不了结果就是防火墙没放行。下面是我在实际部署中比较喜欢的一套版本组合稳定性和兼容性经过很多次验证组件版本建议说明操作系统CentOS 7.9 / Rocky Linux 8.xRHEL系运维资料最多Nginx1.20.x / 1.24.x稳定版别追最新MySQL5.7 / 8.08.0性能更好但要注意认证插件PHP7.4 / 8.0跑Discuz建议7.4兼容性最稳我自己的主力论坛用的是PHP 7.4 MySQL 5.7不是不想用新版而是老插件兼容性这东西越经典的论坛程序越保守。后面你换插件时就会明白稳定压倒一切。2.2 Nginx安装与基础配置先安装Nginx。用yum的话CentOS自带的源里Nginx版本很老建议先添加官方源或者用EPEL源yum install -y epel-release yum install -y nginx systemctl enable --now nginx装好之后先别急着配站点把Nginx的基础配置看一眼。主配置文件在 /etc/nginx/nginx.conf里面默认包含了 /etc/nginx/conf.d/*.conf 这个目录。我习惯把每个站点的配置独立放在 conf.d 下面比如 forum.conf这样以后改起来不会动到主文件。一个最小的论坛站点配置如下server { listen 80; server_name forum.example.com; root /var/www/forum; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.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|css|js|ico)$ { expires 30d; access_log off; } }这里有几个关键点try_files 那一行是为了支持伪静态。论坛的URL看起来像 forum.php?modforumdisplayfid2但可以用伪静态转成更友好的路径比如 forum-2-1.html。这个后面会细说。location ~ .php$ 是让Nginx把PHP请求转发给PHP-FPM。很多新手在这步出错最常见的问题是SCRIPT_FILENAME路径不对导致PHP找不到文件。静态文件的 expires 30d 是告诉浏览器缓存这些资源30天能显著减轻服务器压力。2.3 MySQL/MariaDB安装与初始调优数据库我推荐直接用MariaDB因为CentOS自带源里的MySQL版本实在太老而MariaDB是MySQL的一个分支兼容性很好命令也基本一样。安装很简单yum install -y mariadb-server systemctl enable --now mariadb mysql_secure_installationmysql_secure_installation 这个命令会引导你设置root密码、删除匿名用户、禁止root远程登录、删除测试数据库。一定不要跳过生产环境最基本的数据库加固就是从这里开始的。数据库装好后需要做两件和论坛相关的事。第一件是创建论坛用的数据库和用户CREATE DATABASE forum CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER forum_userlocalhost IDENTIFIED BY 你的强密码; GRANT ALL PRIVILEGES ON forum.* TO forum_userlocalhost; FLUSH PRIVILEGES;注意字符集我特意用了 utf8mb4 而不是老的 utf8。因为DiscuzX 3.5之后全面支持utf8mb4只有这个字符集才能正常存储表情符号比如发帖时带个emoji。用utf8的话遇到特殊字符会报错或直接变成问号。初始调优方面我最常改的是这几个参数写在 /etc/my.cnf 的 [mysqld] 段innodb_buffer_pool_size 512M innodb_log_file_size 64M max_connections 200 query_cache_type 0innodb_buffer_pool_size 是InnoDB引擎的缓存池论坛这种读写频繁的应用把它设成可用内存的一半左右比较合适。query_cache_type 0 是因为MySQL 8.0已经废弃了查询缓存旧版本的查询缓存命中率在论坛场景下很低开着反而拖慢速度。2.4 PHP-FPM安装与扩展PHP是LNMP里最容易出幺蛾子的一环。我推荐用Remi源来装新版PHPyum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm yum install -y yum-utils yum-config-manager --enable remi-php74 yum install -y php php-fpm php-mysqlnd php-gd php-xml php-mbstring php-json php-curl php-zip php-pecl-fileinfo装完后处理两个关键配置第一修改 /etc/php-fpm.d/www.conf 里的运行用户。默认是apache用户但我们的Nginx用的是nginx用户如果不改PHP创建的缓存文件、上传的文件Nginx可能没权限读。改成user nginx group nginx listen.owner nginx listen.group nginx第二PHP-FPM默认监听在127.0.0.1:9000端口这个不用改保持默认就行。但要注意Nginx配置里的 fastcgi_pass 必须和这里一致要么都用端口要么都用socket混用会导致502。PHP装好后可以建一个测试文件验证echo ?php phpinfo(); ? /var/www/forum/info.php然后浏览器访问 http://你的域名/info.php能看到PHP信息页就说明Nginx和PHP之间的桥梁已经通了。验证完记得删掉这个文件它会把服务器环境暴露给所有访问者。3. 论坛程序上架以Discuz! X为例3.1 论坛选型与版本选择论坛程序有很多选择PHP的有DiscuzX、phpBB、XenForo新的还有Flarum、NodeBB。我的建议是如果你做的是中文社区想开箱即用DiscuzX是最合适的。它不是性能最好的但它的后台管理、版块权限、用户评分体系最完善而且中文搜索资料最多遇到问题基本都能找到答案。版本方面现在不要再用老旧的3.2、3.3那些版本有很多已知安全漏洞。直接去Discuz官网下载X3.5正式版它对PHP 7.4和MySQL 5.7的支持已经很成熟还默认加入了验证码、防注册机等安全机制。下载下来的通常是一个 upload 目录里面就是完整的程序文件。我的习惯是先解压到临时目录然后用 rsync 同步到网站目录这样可以顺便排除掉一些不需要的文件rsync -av --exclude*.bak upload/ /var/www/forum/3.2 下载上传与目录权限很多新手在这一步栽跟头其实不是程序有问题而是权限没给对。DiscuzX运行时要写缓存、要生成附件目录如果目录属主不对安装向导会提示目录不可写。我建议的权限分配是这样的chown -R nginx:nginx /var/www/forum chmod -R 755 /var/www/forum chmod -R 777 /var/www/forum/data /var/www/forum/config看到777别害怕这里只对 data 和 config 目录放开写权限因为安装时程序需要往里面写入配置文件。安装完成之后我一般会把 config 目录收回来改成755config_global.php 改成644防止被恶意写入。还有一个容易忽略的点如果你打算用Redis或Memcached做缓存需要提前装好PHP扩展不然后台的缓存设置会报错。不过初始安装阶段不用管缓存先把基本流程跑通。3.3 安装向导与数据库配置浏览器访问 http://你的域名/正常情况下会跳到安装向导。这时候你需要填数据库信息、管理员账号、站点名称等。配置如下配置项填写内容数据库服务器localhost数据库名forum数据库用户forum_user数据库密码你设置的强密码管理员账号自定义不要用admin这种常见名管理员密码至少12位大小写数字特殊符号安装过程中向导会检测PHP函数是否可用、目录是否可写。如果之前PHP扩展装全了这一页基本都会是绿色勾。如果哪一项打红叉严格按照提示补装对应扩展就行不要想着跳过跳过之后论坛会出现各种诡异问题。安装完成后向导会提示你删除 install 目录。这一步必须做不然任何人都能通过访问 install/index.php 重置你的论坛数据这是最容易被忽略的安全漏洞。3.4 伪静态与URL设置DiscuzX的URL美化是论坛可玩性的重要一环。默认的URL是 /forum.php?modforumdisplayfid1 这种形式又长又丑还不利于搜索引擎收录。在后台开启伪静态后会变成 /forum-1-1.html 的静态格式好看很多。开启方法分成两步。第一步到后台“全局 - SEO设置 - URL静态化”勾选你想静态化的模块。第二步在Nginx的站点配置里加入Discuz的伪静态规则location ~* ^/(forum|thread|home|space|group|user|blog|album).*\.html$ { rewrite ^/([a-z])-([0-9])-([0-9])\.html$ /$1.php?mod$1fid$2page$3 last; rewrite ^/([a-z])-([0-9])-([0-9])-([0-9])\.html$ /$1.php?mod$1tid$2page$3 last; }伪静态本质上不是静态页面它只是让URL看起来像静态实际还是走PHP处理。它的主要作用是美化URL和利于SEO对性能提升其实有限。所以千万别以为开了伪静态就能扛更多并发那是不切实际的。4. 上线前的配置调优和安全性加固4.1 PHP-FPM与Nginx性能参数调整论坛上线前要根据服务器实际配置调整PHP-FPM的参数。默认配置是给开发环境用的直接上生产会有两个问题一是进程数太少并发一高就502二是内存设置太大小机器直接崩。我常用的调整策略是查看服务器内存然后决定进程数和内存限制pm dynamic pm.max_children 20 pm.start_servers 5 pm.min_spare_servers 5 pm.max_spare_servers 10 pm.max_requests 500这里的 pm.max_children 表示PHP-FPM最多同时处理多少个请求。没有一个绝对正确的数值但可以按“每个进程约30M内存”来估算。2G内存的机器留出512M给MySQL1G给PHP那么 max_children 设在20左右比较合理。pm.max_requests 500 是我特别喜欢的一个参数它让每个PHP进程在处理完500个请求后自动重启一次可以有效避免PHP内存泄漏导致进程越来越大。论坛跑个把月内存占用是不是持续上涨就看这个参数有没有设对。Nginx方面主要是调整事件模型和连接数。在 nginx.conf 的 events 段里worker_processes auto; events { worker_connections 1024; }worker_processes auto 会自动匹配CPU核心数。worker_connections 表示每个进程能同时保持的连接数默认1024够用但如果你预期并发很高可以调到2048。改完需要重载Nginxnginx -t systemctl reload nginx4.2 MySQL连接数与缓存优化论坛最怕的就是数据库崩。而数据库最容易崩的原因就是连接数不够或者慢查询太多。连接数方面前面已经设了max_connections 200这是普通论坛的合理值。但要注意每个PHP-FPM进程都可能占用一个数据库连接所以如果PHP-FPM的max_children是20那么连接数至少要大于20不然高峰期会出现“Too many connections”的错误。慢查询排查也是上线前必须做的一件事。在MySQL里打开慢查询日志slow_query_log 1 slow_query_log_file /var/log/mysql-slow.log long_query_time 2这样超过2秒的SQL语句会被记录到日志里。论坛跑一周后去看这个日志凡是经常出现的慢查询都要重点关注。DiscuzX这类程序最典型的慢查询往往出在搜索功能上如果搜索词没有被索引全表扫描会很致命。优化方案通常是三个步骤先给关键字段加索引比如帖子表的 fid、tid、dateline再用Memcached或Redis缓存热门帖子列表最后实在扛不住就把搜索功能换成全文搜索引擎比如Xunsearch或者Elasticsearch。但这是后期的故事了初期做好前两步就够了。4.3 常用安全配置论坛是攻击重灾区因为注册是开放的任意用户都能提交内容SQL注入、XSS、CC攻击都是家常便饭。上线前有几个安全项必须做第一修改默认后台路径。DiscuzX默认后台是 admin.php很容易被扫描器发现。我的做法是先改文件名比如改成 custom_admin.php然后在Nginx里对这个路径加一个访问密码location ^~ /custom_admin.php { auth_basic Administrator Login; auth_basic_user_file /etc/nginx/.htpasswd; include fastcgi_params; fastcgi_pass 127.0.0.1:9000; }这样就算有人猜到了路径还得再输入一层用户名密码才能进入后台。虽然有些麻烦但对比论坛被黑的代价这点麻烦完全值得。第二隐藏Nginx和PHP版本号。在 nginx.conf 的 http 段里加server_tokens off;同样在 php.ini 里设置expose_php Off这一步很简单但能让扫描器多费一点功夫。第三禁止上传目录执行PHP。论坛的附件目录 /data/attachment 会被上传很多文件攻击者经常往这里传webshell。在Nginx配置里加location ~* ^/data/attachment/.*\.(php|php5|phtml)$ { deny all; }这条规则告诉我们附件目录只能当作静态文件来源绝不能让任何PHP文件在里面执行。4.4 备份策略我见过太多人辛辛苦苦搭好论坛结果数据丢了束手无策。备份这件事必须在一开始就建立机制而不是等出了问题再补救。我的备份方案分两层。第一层是数据库备份用crontab每天凌晨执行mysqldump -uforum_user -p密码 forum --single-transaction --default-character-setutf8mb4 | gzip /backup/forum_$(date %Y%m%d).sql.gz--single-transaction 是MySQL的InnoDB引擎在线备份参数备份过程中不会锁表用户访问不受影响。默认字符集指定为utf8mb4防止备份文件里中文乱码。第二层是附件备份用rsync同步到另一台机器rsync -avz /var/www/forum/data/attachment/ backup另一台机器:/backup/attachment/数据库每天备份附件每周同步一次。备份保留最近7天太老的备份可以自动清理。如果你用的是云服务器强烈建议再加一个云快照那是最后一道防线服务器被整台搞挂时还能整体恢复。5. 实操中的常见问题与排查笔记5.1 常见故障速查表LNMP环境的报错绝大多数都集中在几个固定环节。我整理了一张速查表基本覆盖了新手时期最容易遇到的问题现象常见原因解决方法浏览器访问返回502 Bad GatewayPHP-FPM没启动或Nginx指错了地址systemctl status php-fpm确认fastcgi_pass和php-fpm监听一致返回403 Forbiddenindex.php缺失或目录权限不对检查站点root路径是否存在index.php确认目录有读权限安装向导提示目录不可写data/config目录属主不对chown -R nginx:nginx 整个站点目录再设置755数据库连接失败数据库名/用户/密码填错或者MySQL没启动在服务器用mysql命令登录测试排除网络和认证问题上传头像或附件失败目录无写权限或PHP上传大小限制检查attachment目录写权限修改php.ini的upload_max_filesize页面能开但样式全乱伪静态规则和静态资源路径冲突检查Nginx配置里静态文件location确认css/js能正常访问后台开启静态化后404伪静态规则不完整确认Nginx已加载Discuz的rewrite规则重载Nginx5.2 几个典型的排查过程第一个我要讲的是502问题。曾经有朋友找我帮他查502他描述是“装完LNMP打开首页就是502”。我远程上去第一件事就是看PHP-FPM状态结果发现php-fpm服务根本没启动。问他为什么没启动他说安装完成后忘了 systemctl start php-fpm。这个案例看起来很蠢但确实很多。提醒大家LNMP三个服务要一个一个确认状态systemctl status nginx systemctl status php-fpm systemctl status mariadb三个服务全部是active running再去查配置问题。顺序反了会浪费很多时间。第二个经典问题是我自己踩过的坑Nginx配置里 index 没加 index.php。当时我新建了一个站点目录下既有 index.html 又有 index.phpNginx默认优先找index.html所以怎么访问都是静态页面后台入口完全进不去。后来我在配置里把 index 顺序改成 index.php index.html问题才解决。第三个是字符集相关的坑。有段时间论坛发帖带表情符号就报错数据库写入失败。排查到最后发现是数据库表和字段的字符集都是utf8不是utf8mb4。这个问题的本质是MySQL 5.7默认字符集是latin1而我建库时虽然指定了utf8mb4但表结构是从老版本升级来的字段级别还是utf8。解决办法是把存量表全部转换ALTER TABLE pre_forum_post CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;论坛有好几十张表我写了条SQL语句遍历所有表批量转换这才彻底根治。如果你是从老Discuz升级上来的这个坑一定要留意。5.3 经验心得跑LNMP论坛这几年来我最大的感受是99%的问题其实都不是技术难度问题而是基础配置问题和环境差异问题。同一个教程在不同系统、不同PHP版本下就可能跑不通所以一定要学会自己看日志。Nginx的错误日志在 /var/log/nginx/error.logPHP-FPM的日志在 /var/log/php-fpm/logMySQL的日志在 /var/log/mariadb/mariadb.log。出问题时第一个动作就是打开对应的日志文件看最后几十行报错。大部分答案都在日志里比到处搜索提问高效得多。我解决问题最快的几次全是日志直接指路的。另外一点不要迷信“一键安装包”。市面上有很多LNMP一键脚本我也用过确实省事但坏处是你不知道它到底改了什么配置出问题时无从下手。手动安装一次你会对整个环境的结构很清楚后面出了问题能自己排。我建议新手至少手动搭一次以后再决定要不要用脚本。6. 写在最后一些个人的建议6.1 新手容易忽略的细节有几个细节是我反复提醒身边朋友注意的第一时区设置。PHP的 php.ini 里有一个 date.timezone 参数默认可能是UTC导致论坛发帖时间比本地时间差8小时。把它改成date.timezone Asia/Shanghai然后重启PHP-FPM。这个问题不会让论坛报错但会让所有置顶帖的显示时间都不对劲很容易被忽略。第二swap分区。如果你的服务器内存只有1G建议加2G的swap。装LNMP的过程中MySQL初始化内存使用会有一个小高峰没有swap的话可能被OOM killer杀掉进程。加swap的方法dd if/dev/zero of/swapfile bs1M count2048 chmod 600 /swapfile mkswap /swapfile swapon /swapfile这条命令会创建一个2G的swap文件对低配服务器来说相当于安全气囊宁可用不到也不能没有。第三HTTPS不是可选。现在搜索引擎对HTTPS站点有明显偏好浏览器也会对纯HTTP站点标红警告。我建议域名解析完成之后就去申请免费的SSL证书比如Lets Encrypt或各大云的免费证书。Nginx配置HTTPS其实就是在server段里加几行把443端口监听上再把80端口重定向到443就行。6.2 后续扩展方向论坛搭好只是第一步。跑起来之后你会陆续遇到性能瓶颈和新需求这时候再一步一步扩展。我的建议是优先做缓存。DiscuzX支持Memcached和Redis装好PHP扩展后在后台开启能把数据库查询压力降一个量级。然后考虑做附件云存储把图片上传到OSS/COS这类对象存储减轻本地磁盘压力。再往后就是CDN、负载均衡这些但那是日活过万以后才需要考虑的事了。架设论坛的过程本质上是一次完整的服务器运维实战。你把LNMP从无到有搭出来等于把Linux操作、Web服务配置、数据库管理、PHP运行机制全部走了一遍这些东西在任何后端开发场景都用得上。所以别急着追求完美先把它跑起来再慢慢优化。
返回列表