LNMP架构+wordpress实现动静分离

WordPress简称WP,最初是一款博客系统,后逐步演化成一款免费的CMS(内容管理系统/建站系统)。

WordPress网站的适用场景:

  • 博客

  • 企业官网

  • 作品集网站

  • 电商平台

  • 线上教育系统

  • 论坛和社群网站

  • 甚至会员系统订阅内容平台……

1 环境说明

系统安装软件IP服务角色
centos7nginx+mysql数据库192.168.42.28代理服务器
centos7nginx+wordpress(加载静态资源)192.168.42.29静态服务器
centos7nginx+php+wordpress(加载动态资源)192.168.42.30动态服务器

软件安装略

2 代理服务器配置

vim wordpress.conf

upstream static {server 192.168.42.29:8080;
}
​
upstream dynamic {server 192.168.42.30:80;
}
​
server {listen 80;server_name 192.168.42.28;
​location / {proxy_pass http://dynamic;proxy_set_header Host $http_host;   # 保留原始请求的 Host 头proxy_set_header X-Real-IP $remote_addr;   # 传递客户端的真实 IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 添加客户端 IP 到代理链proxy_set_header X-Forwarded-Proto $scheme;   # 传递原始请求协议(http/https)}
​# 静态资源:WordPress 的 uploads、themes、plugins 目录location ~* ^.+\.(css|js|jpg|jpeg|png|gif|svg|ico|woff|woff2|ttf|eot)$ {rewrite ^/wordpress(/.*)$ $1 break;  # 移除路径前缀proxy_pass http://static;  # ← WordPress根目录expires 30d;add_header Cache-Control "public, no-transform"; # 允许所有缓存(包括 CDN),禁止代理修改内容(如压缩图片)proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;
​# 调试日志(生产环境可移除)access_log /var/log/nginx/static-access.log;error_log /var/log/nginx/static-error.log notice;}
}

改完重启nginx:

systemctl restart nginx

此节点需要安装mysql数据库,安装过程略。

数据库需要创建一个wordpress库,并创建一个wordpress用户用来给其他节点连接数据库,并赋予这个用户这个库的权限。

CREATE DATABASE wordpress;  # 创建一个新的数据库
CREATE USER 'wordpress'@'%' identified with mysql_native_password by 'Nebula@123'; # 创建一个新用户
GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'%';  # 赋予用户对 “wordpress” 数据库的全部权限。
FLUSH PRIVILEGES;

3 静态服务器配置

vim static.conf

server {listen 8080;server_name 192.168.42.29;
​# 添加wordpress路径层location /wordpress {alias /opt/wordpress;  # 使用alias精确匹配路径try_files $uri $uri/ =404; # 按顺序尝试访问文件或目录,如果都找不到,则返回404。}
​location ~* ^.+\.(css|js|jpg|jpeg|png|gif|svg|ico|woff|woff2|ttf|eot)$ {root /opt/wordpress;}
}

改完重启nginx服务

systemctl restart nginx

4 动态服务器配置

wordpress版本跟php版本对应关系:

WordPress 版本最低支持 PHP 版本推荐 PHP 版本
4.xPHP 5.2.4PHP 5.6 – 7.1
5.xPHP 5.6PHP 7.0 – 7.4
6.0 – 6.2PHP 5.6PHP 7.4 – 8.2
6.3 – 6.5PHP 7.0PHP 7.4 – 8.3
6.6 – 6.8+PHP 7.2PHP 7.4 及以上

wordpress这里我选择5.x的版本,centos 7 默认的 php 版本为5.4,太多老旧,因此我们需要升级php

# 执行下面的命令升级软件仓库
rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
​
# 执行下面的命令删除php
yum remove php-common
​
# 安装php 5.6版本(php56w-devel这个不是必需的)
yum install -y php56w php56w-opcache php56w-xml php56w-mcrypt php56w-gd php56w-devel php56w-mysql php56w-intl php56w-mbstring
​
# 如果是nginx ,则还需要安装 php56w-fpm
yum install php56w-fpm -y

启动php服务

systemctl restart php-fpm

下载wordpress

 wget https://cn.wordpress.org/wordpress-5.6.14-zh_CN.tar.gz

解压wordpress到nginx发布目录,并配置数据库连接

tar -zxvf wordpress-5.6.14-zh_CN.tar.gz -C /usr/share/nginx/html/
cd /usr/share/nginx/html/wordpress
cp wp-config-sample.php wp-config.php
vim wp-config.php

编辑wp-config.php文件23-32行关于数据库连接的相关信息,确保配置正确。

配置nginx访问fastcgi进行php解析

vim php.conf

server {listen 80;server_name 192.168.42.30;
​location / {root   /usr/share/nginx/html;index  index.html index.htm index.php;}
​location ~ \.php$ {root           /usr/share/nginx/html;fastcgi_pass   127.0.0.1:9000;fastcgi_index  index.php;fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;include        fastcgi_params;}
}

重启nginx服务

systemctl restart nginx

5 访问测试

浏览器访问“http://代理服务器IP地址/wordpress”进入安装向导。

这里我的代理服务器为192.168.42.28,因此地址为http://192.168.42.28/wordpress

设置站点标题、管理员账号、密码和邮箱,并单击“安装 WordPress”。

参数说明
站点标题WordPress网站名称。
用户名WordPress管理员名称。
密码可以使用默认的密码或者自定义密码。请勿重复使用现有密码,并确保将密码保存在安全的位置。
您的电子邮箱地址接收通知的电子邮件地址。

安装完成后,弹出安装成功界面。

单击“登录”,或者浏览器访问“http://服务器IP地址/wordpress/wp-login.php”,输入用户名/电子邮箱地址和密码后单击“登录”,进入WordPress。

登录成功后进入主界面,就可以愉快玩耍了。

 

6 过程中问题解决

6.1 问题现象和旧配置

原来旧的配置,在做的过程中,遇到无法加载页面样式,导致静态页面访问都是404(浏览器F12打开查看有很多静态资源404)。

# 代理服务器配置
upstream static {server 192.168.42.29:8080;
}
​
upstream dynamic {server 192.168.42.30:80;
}
​
server {listen 80;server_name 192.168.42.28;
​location / {proxy_pass http://dynamic;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
​# 静态资源:WordPress 的 uploads、themes、plugins 目录location ~* ^.+\.(css|js|jpg|jpeg|png|gif|svg|ico|woff|woff2|ttf|eot)$ {proxy_pass http://static;  # ← WordPress根目录expires 30d;add_header Cache-Control "public, no-transform";try_files $uri =404;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}
# 静态服务器配置为
server {listen 8080;server_name 192.168.42.29;
​location / {root /opt/wordpress;index index.php;}
​location ~* ^.+\.(css|js|jpg|jpeg|png|gif|svg|ico|woff|woff2|ttf|eot)$ {root /opt/wordpress;}
​
}

6.2 问题分析

分析可能的原因

  1. 静态资源的路径问题:当我们访问http://192.168.42.28/wordpress/时,页面会加载一些静态资源,比如CSS文件。这些静态资源的URL路径可能是以/wordpress/开头的。但是我们的静态服务器配置中,root是/opt/wordpress,那么静态服务器期望的路径是/opt/wordpress下的文件。然而,当我们请求一个CSS文件时,例如http://192.168.42.28/wordpress/wp-content/themes/style.css,代理服务器会将其代理到静态服务器的/wordpress/wp-content/themes/style.css路径,而静态服务器会在/opt/wordpress/wordpress/wp-content/themes/style.css路径下寻找文件,这显然是不正确的,因为我们的wordpress文件应该直接位于/opt/wordpress下,而不是还有一级wordpress目录。

  2. 另外,动态服务器上,root是/usr/share/nginx/html,那么WordPress程序应该放在该目录下。同样,如果我们将WordPress放在/usr/share/nginx/html/wordpress目录下,那么访问路径应该是http://192.168.42.28/wordpress/,这样动态服务器需要能够正确解析到/usr/share/nginx/html/wordpress目录下的文件。

  3. 静态服务器的配置中,我们设置了两个location块,但是都没有处理/wordpress/路径下的静态文件。静态服务器的root设置为/opt/wordpress,那么当请求/css/style.css时,它会去/opt/wordpress/css/style.css找。但是我们的请求是/wordpress/wp-content/...,所以静态服务器需要知道文件在/opt/wordpress/wordpress/wp-content/...?这显然不对。

总结原因:

  1. 路径不匹配

    • 访问URL:http://192.168.42.28/wordpress/

    • WordPress生成的静态资源URL路径为:/wordpress/wp-content/themes/.../style.css

    • 静态服务器(192.168.42.29)的root目录是/opt/wordpress,它期望的请求路径是/wp-content/...(无/wordpress前缀)

    • 实际请求路径包含/wordpress前缀,导致静态服务器在/opt/wordpress/wordpress/...路径下查找文件(路径错误)

  2. 配置缺陷

    • 代理服务器的静态location直接转发原始URI(含/wordpress前缀)到静态服务器

    • 静态服务器未处理/wordpress路径前缀

6.3 解决方案

修改静态服务器配置

在静态服务器的Nginx配置中添加/wordpress路径解析:

server {listen 8080;server_name 192.168.42.29;
​# 关键修改:添加wordpress路径层location /wordpress {alias /opt/wordpress;  # 使用alias精确匹配路径,将请求中的/wordpress映射到物理路径/opt/wordpresstry_files $uri $uri/ =404;}
​location ~* ^.+\.(css|js|jpg|jpeg|png|gif|svg|ico|woff|woff2|ttf|eot)$ {root /opt/wordpress;}
}

修改代理服务器配置

在代理服务器的静态location中重写URI路径:

location ~* ^.+\.(css|js|jpg|jpeg|png|gif|svg|ico|woff|woff2|ttf|eot)$ {# 关键修改:移除URI中的/wordpress前缀rewrite ^/wordpress(/.*)$ $1 break;  # rewrite规则将/wordpress/wp-content/...重写为/wp-content/...proxy_pass http://static;... # 其他配置保持不变
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/91040.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/91040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智慧灯杆:不止于照明,塔能科技的城市感知网络野心

当夜幕悄然降临,城市里的路灯便依次亮了起来,它们可不单单照亮了行人前行的路以及车辆行驶的道路,实际上还在悄无声息地经历着一场变革。现如今的路灯,早已不再仅仅充当单纯的照明工具这么一个角色了,而是逐渐转变成了…

【Linux内核模块】调试技巧

内核模块开发最让人头疼的不是写代码,而是调试 —— 代码编译通过了,加载后却要么没反应,要么直接让系统崩溃。这就像在黑屋子里修机器,看不见摸不着。其实内核调试有一套成熟的工具箱,掌握这些工具和技巧,…

RK3568笔记九十一:QT环境搭建

若该文为原创文章,转载请注明原文出处。 记录按照正点原子给的手册搭建QT环境 参考《09【正点原子】ATK-DLRK3568_Qt开发环境搭建V1.2.pdf》 一、安装 1、下载 https://mirrors.sau.edu.cn/qt/archive/online_installers/4.6/qt-unified-linux-x64-4.6.0-online.run 2、赋…

面试实战,问题十六,Java面试,消息队列,如何避免消息重复消费,怎么回答

在Java面试中,关于消息队列如何防止消息被重复消费的问题,可以从以下几个方面进行回答,结合系统架构设计、消息队列机制和业务逻辑处理,确保在不同场景下实现消息的幂等性。 1. 消息队列重复消费的根本原因 消息重复消费的根本原因…

PDF转图片实用指南:如何批量高效转换?

将PDF转换为图片后,可以更方便地在演示文稿、网页或电子相册中使用这些资料,以便更好地展示信息。它 是一款支持多文件批量转换的工具,可将多个 PDF 文档一键转换为图片格式。虽然界面为英文,但操作简单,不影响使用。你…

走入Linux的世界:编辑器Vim

嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的pa…

PyTorch中神经网络的模型构建

要构建自定义模型,需完成两个核心步骤:继承 nn.Module 类;重载 __init__ 方法(初始化)和 forward 方法(前向计算) 神经网络的构造 初始化方法(__init__) def __init__…

QML QtCharts坐标轴系统

QtCharts是Qt框架中强大的数据可视化模块,它提供了丰富的图表类型和灵活的坐标轴系统,能够满足各种数据展示需求。本文将全面介绍QML中QtCharts的坐标轴系统,包括数值坐标轴(ValueAxis)、对数坐标轴(LogValueAxis)、分类坐标轴(CategoryAxis)…

TI 2025全国电赛猜题

本科组可能的题目方向本科组器材更侧重高频信号处理、复杂控制系统、精密测量及多设备协同,可能涉及以下题目:四旋翼飞行器相关任务题目示例:设计 “基于四旋翼的 UV 光控自主导航系统”任务要求:利用四旋翼飞行器(最大…

Python自动化运维实战指南

什么是自动化运维定义与背景自动化运维是指利用工具和脚本自动执行传统上需要人工操作的IT运维任务,包括但不限于服务器配置管理、软件部署、监控告警、日志分析等日常工作。随着互联网业务规模的扩大,传统手工运维方式已无法满足快速部署、规模化管理等…

k8s的csi对接GPFS

在 Kubernetes(k8s)集群中,通过 CSI(Container Storage Interface)对接 GPFS(General Parallel File System,现为 IBM Spectrum Scale)是实现高性能共享存储的重要方案。GPFS 作为并…

HTB赛季8靶场 - era

nmap扫描 └─$ nmap -p- --min-rate 1000 -T4 10.129.137.201 -oA nmapfullscan Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-07-27 21:19 EDT Warning: 10.129.137.201 giving up on port because retransmission cap hit (6). …

Bug猫学习史#1:面向对象

在Java编程中,掌握几个核心概念对深入学习至关重要:类属性建议采用包装类以提升灵活性;建造者模式中this关键字能有效简化对象构建过程;static关键字涉及类的加载机制;接口默认使用public修饰符并支持默认方法实现&…

优测推出HarmonyOS全场景测试服务,解锁分布式场景应用卓越品质!

随着HarmonyOS NEXT“纯血鸿蒙”的全面商用,生态正以前所未有的速度重构终端操作系统格局。对于APP厂商而言,应用测试需要从单一设备思维向场景化服务验证转变。优测云服务平台正式推出 HarmonyOS全场景测试解决方案,针对鸿蒙系统提供功能测试…

二层环路与三层环路:原理、区别与解决方案全解析

网络环路是网络运维中最常见也最具破坏性的问题之一。本文将深入浅出地解析二层环路和三层环路的核心概念,通过对比分析帮助读者全面理解这两种环路的形成机制、危害表现及解决方案。一、环路问题概述 1.1 什么是网络环路 网络环路是指数据包在网络中循环传输无法到…

Python爬虫库性能与选型实战指南:从需求到落地的全链路解析

目录 一、性能基准测试:用数据打破认知误区 1. 静态页面采集:效率与资源的终极对决 2. 动态页面渲染:速度与真实性的博弈 二、场景化选型矩阵:从需求到工具的精准映射 1. 小规模快速原型开发(≤1000页)…

uni-app switch(开关选择器) BUG

uni-app switch(开关选择器) BUGBUG:uni-app中的switch的checked属性并不能根据根据绑定的动态数据进行调整switch开关选择器(BUG)switch开关选择器(BUG) - 我的使用用途switch开关选择器&#…

微服务架构中的资源调度与负载均衡实践

更多云服务器知识,尽在hostol.com在今天这个快速发展的数字化时代,微服务架构已经成为了现代企业系统开发的主流。随着技术的不断进步,企业的业务需求也在不断地变化,传统的单体架构已经无法满足日益复杂的应用需求。微服务架构&a…

Rust Web 全栈开发(十一):WebAssembly 尝鲜

Rust Web 全栈开发(十一):WebAssembly 尝鲜Rust Web 全栈开发(十一):WebAssembly 尝鲜什么是 WebAssembly?安装 wasm-pack 和 cargo-generate使用项目模板构建项目生成网页安装依赖项在 www 中使…

Thymeleaf实战:SpringBoot用户管理系统

Thymeleaf 示例代码下面是完整代码示例,帮助理解 Thymeleaf 语法和后端代码的配合:1. 用户实体类 (User.java)/*** 用户实体类*/ public class User {private Long id; // 用户IDprivate String name; // 用户名private String email; /…