在 腾讯云 RockyLinux 9.3 上用 PHP、MariaDB、nginx 安装 WordPress 2024-09-16 / 210 次 / 快抢沙发 /

RockyLinux 9.3: WordPress(PHP + MariaDB + nginx) + https

最近需要用 WordPress 快速搭建一个简单的博客站点,暂时不需要进行网站备案,如果你也有和我一样的需求,可以考虑下我的服务器及相关工具、中间件及软件的选择;为了更好的熟悉技术细节,我这次采用的方法是更难一点的从零到一方式安装,不用开箱即用的已经安装好了 WordPress 的系统镜像,也不用一键安装包,更不用 Docker 容器之类的;

温馨提醒:以下新手教程,内容虽然有点长,但是值得一读。

相关环境选择:

服务器 & 域名 & SSL 证书托管商:腾讯云
说明:用户体验相对新手来说比较好;

之所以选择腾讯云,是因为他的用户体验相对新手很友好,很多的管理配置,都是傻瓜式的,很好操作,也利于不懂太多技术的新手,所以我当前正规且用户群体在国内的网站服务器、域名、SSL 证书都在腾讯与上;虽然说国内的服务器需要备案这一个缺点,如果你做的是正常的站点,还是建议做一下网站备案,现在网站备案也没有以前那么复杂了,如果不想备案,也可以购买香港或者海外的服务器,不用备案,可以直接上线,就是价格贵些、访问速度差点,推荐不想备案或者当前不想备案,就选择购买香港地区的服务器。

有人可能会想我为何不用阿里云,我不低估阿里云的技术实力,但是我一直更喜欢腾讯云的网站交互设计风格,以及跟 QQ 和微信更好的绑定管理,是让我选择腾讯云的最大理由。

选择国内的服务器托管商,有一个可能潜在风险:如果你购买的服务器是属于大陆地区的,就要求你备案,并且如果你的域名在海外服务商,可能要求你转入到当前国内的服务器托管商,并且万一你的网站受到了一些特殊因素的影响,很有可能域名拿不回来了,服务器不可用,数据丢失不是最可怕的,域名被禁掉并且不能转移,是最恐怖的,已经有类似的情况发生了,所以大家要综合评估这个风险。

服务器:RockyLinux 9.3
说明:服务器的选择肯定优先选择 Linux,经过多方对比选择 RockyLinux;

服务器优先选择 Linux,但是具体哪个发行版,我个人之前喜欢用 CentOS,但是由于 CentOS 的发行模式有所变化,已经不推荐作为生产环境使用,经过多方对比,我个人还是会选择 RockyLinux(可以理解为更稳定的 CentOS 版本),由于我选择的腾讯云作为服务器托管商,当前里面最新的 RockyLinux 就是 9.3 版本了,如果有朋友喜欢用 CentOS Stream,Ubuntu Server 等等,都可以,只要你自己熟悉觉得没有问题,先用起来,有问题再说。

网站程序:WordPress
说明:网站搭建的时候,选择当前最新版本的 WordPress;

相对 WordPress,为何不选择一些其他的比较新的网站程序,尤其是 Ghost,我不否认 Ghost 也不错,但是没有 WordPress 的功能强大,尤其是周边的插件和主题,特别多,开发生态很好;这个也就是为何我选择 WordPress 的原因。

开发语言:PHP
说明:网站搭建的时候,选择当前方便安装的最新版本 PHP;

由于 PHP 是当前 WordPress 的主要开发语音,因此需要安装 PHP,这个毋庸置疑。

数据库:MariaDB
说明:网站搭建的时候,选择当前方便安装的最新版本 MariaDB;

WordPress 官方推荐支持的数据库就 MySQL 和 MariaDB,由于 MariaDB 更加开放,所以选择 MariaDB。

Web 服务器:nginx
说明:网站搭建的时候,选择当前方便安装的最新版本 nginx;

常见的 Web 服务器有 Apache 和 nginx,由于个人的喜好,一直选用的是 nginx。

本地环境:macOS
说明:本地电脑环境我一直用的是 macOS,已经用的很习惯了;

本地环境一直用的 macOS,相对于 Windows 的区别,就在于一些和服务器操作相关的 SSH 和 FTP 工具选择有所不同。

服务器工具:Termius + FileZilla
说明:SSH 和 FTP 工具;

由于我用的本地电脑是 macOS,所以我的服务器工具选择 Termius(SSH/FTP) + FileZilla(FTP) 组合,还行;当然也有很多其他的工具,完全看个人的喜好;不过如果你是 Windows 用户,建议试试 MobaXterm 这个 SSH + FTP 工具,我个人是很喜欢的,真的很好用。

Step 1:购买服务器
说明:腾讯云香港云服务器;

由于我的目标是快速上线站点,所以选择不需要备案且速度还行的香港云服务器,当然轻量级应用服务器,也是可以选择使用的,虽然好像没有我喜欢的 RockyLinux,但价格是云服务器的 1/3 左右,而且可能有一个问题,上面提醒:无法保障中国内地与香港之间的跨境公网质量,在跨境连接时可能出现较大网络延迟和丢包,所以个人还是建议选择更贵一些的云服务器。

我们登录进入腾讯云,来购买腾讯云服务器:

tencent-cloud-cvm-purchase-step-1


基础配置:
计费模式:包年包月;
地域:中国香港;
可用区:选择推荐;
实例配置:
架构:X86 计算;
实例族:标准型;
类型:全部类型;

tencent-cloud-cvm-purchase-step-2


机型实例:选择最便宜的一款就行;
镜像:公共镜像 RockyLinux,最新版本 9.3;
存储:通用型 SSD 云硬盘,容量 20G;
数据盘:不选;
数据备份:不选;

备注:存储容量选择 20G 就可以了,截图上是 50G,小网站刚开始没有必要;作为新手的话,暂时没有必要去选择数据盘,到时候你又要处理挂载和数据库的位置等问题,而且到时候选择整体做定期自动化磁盘快照就相当于某种程度的“一键数据备份”,这样的话,也没有必要选择数据备份了,自己阶段性的导出数据库本地备份就好;新手小网站,就减少不必要的麻烦,以后需要慢慢再接触和学习;服务器具体购买几个月,自己评估即可。

tencent-cloud-cvm-purchase-step-3


网络与带宽:
网络:选择默认即可;
手动分配地址:不勾选;
公网 IP:勾选分配独立公网 IP;
线路类型:BGP;
带宽计费模式:包月带宽;
带宽值:1Mbps;
IPv6 地址:忽略;
安全组:注意放通 TCP:20/21/22/80/443;
标签:可不选择;

备注:网络选择里面我这边有子网选择的原因是因为我已经有一台同一区域(中国香港)的服务器了,可以先不用深究这个问题,暂时不影响;另外这个里面尤其需要注意的就是选择安全组,如果没有现成的安全组,需要新建安全组,我们一定需要放开的端口有 20/21(FTP)、22(SSH)、80(HTTP)、443(HTTPS);此处的新建里面不包含 20/21(FTP)端口;所以我们要新建安全组;

tencent-cloud-cvm-security-group-setup-1

新建安全组,腾讯云会帮我们默认放开 22(SSH)80(HTTP)443(HTTPS)3389(Windows 远程桌面)和 ICMP(允许服务器被 Ping);

tencent-cloud-cvm-security-group-setup-2

进入到安全组界面,有一个“一键放通”,里面包含我们需要的 20(FTP)端口,直接点击确认:

tencent-cloud-cvm-security-group-setup-3

tencent-cloud-cvm-security-group-setup-4

出站规则默认的完全放通即可,不用管;

tencent-cloud-cvm-security-group-setup-5

通过学习现有的配置规则,我们只需要保留 20/21(FTP)、22(SSH)、80(HTTP)、443(HTTPS)几个端口即可,最终得到以下精简的“入站规则”配置,注意:0.0.0.0/0 代表匹配所有 IPv4 地址,::/0 或者 0::0/0 代表匹配所有 IPv6 地址。云私有网络的配置保留就好。

tencent-cloud-cvm-security-group-setup-6

我们回到上面,选择这个已有安全组作为服务器的安全设置;下一步:

tencent-cloud-cvm-purchase-step-4


实例名称:test;
登录方式:自动生成密码;
实力销毁保护:勾选;
安全加固:勾选;
云监控:勾选;
自动化助手:勾选;
其他:忽略;

这里我们选择自动生成密码,会在你的腾讯云“站内信”里面得到自动生成的 root 用户密码,这样做的好处也相当于你有一个密码备份位置,同时忘记了密码也无所谓,可以在服务器相关设置中重置密码;下一步核对好配置,直接购买即可;记得确认“站内信”里面的包含 root 用户密码的服务器信息,注意公网 IP 地址;

WordPress 搭建 Step 1:通过 SSH 工具登录服务器
说明:登录服务器进行相关的配置和软件安装是第一步:

找到自己的服务器公网 IP 地址,通过 SSH 工具登录我们的云服务器,一般使用自动生成的 root 用户密码登录,新手不建议使用密钥对的方式登录;一般的 SSH 工具都会让你输入服务器公网 IP 地址,端口也会默认 22,填入用户名和密码;点击登录即可;但是你会发现第一步可能就卡住了,因为很有可能登录不上,不要紧,一步步来排查;

问题 1:通过 SSH 工具无法远程登录云服务器
说明:常见的登录失败有三种情况;


情况 1:我们需要登录云服务器,是不是需要 TCP 22 端口开放,才能通过 SSH 登录,我们第一要排查的就是服务器关联的腾讯云安全组里面的“入站规则”是否放通了 TCP 22 端口,如果没有就添加上,如果没有就下一步;


情况 2/3:登录服务器确认 Linux 服务器是否开启了防火墙并且没有放开 22 端口的访问 & 服务器是否允许了 root 用户通过密码的形式登录;

那么问题来了,都不能通过 SSH 远程登录云服务器上去,那么要如何才能查看情况 2/3 呢,腾讯云给了一个在线的云服务器的工具:OrcaTerm 工具(控制台-云服务器),试试看,我们点击进入,有两种登录方式,一种是免密,另外一种是 SSH 登录;

如果以上两种方式都不能登录服务器,就打电话联系腾讯云客服寻求帮忙;

tencent-cloud-cvm-orcaterm-setup-1

tencent-cloud-cvm-orcaterm-setup-2


如果以上两种方式能够登录上去,我们就可以直接用这个 OrcaTerm 工具来进行 SSH 和 FTP 的操作;我们先确认一下当前服务器是否配置了让 root 用户登录:
去到 /etc/ssh 目录下,找到 sshd_config 文件,注意不是 ssh_config 文件;看看里面里面是否有配置 PermitRootLogin yes,如果没有这行配置,或者这行配置被“#”符号注释掉了,那就新增或者打开注释;
注意:我们任何针对文件的修改,最好养成良好的习惯,将当前文件做一个备份操作,命令行:cp *.file *.file.bak;将 *.file 文件备份一个 *.file.bak,这样做的好处就是为了避免来回修改出了问题,你还可以通过恢复初始备份文件来恢复相关的配置;
然后通过 vi 命令直接进入修改:
vi sshd_config
进入文件之后:输入字母 a,开始修改文件,确保加上了 PermitRootLogin yes,修改完成之后,ESC 键退出,然后输入 :wq 退出保存即可;新手如果对 vi 不熟悉,也没有关系,可以通过 OrcaTerm 自带的“文件管理器”,将文件下载到本地用编辑器修改好,再上传上去即可;

[root@VM-0-6-rockylinux etc]# cd /etc/ssh
[root@VM-0-6-rockylinux ssh]# ls
moduli      ssh_config.d  sshd_config.d     ssh_host_dsa_key.pub  ssh_host_ecdsa_key.pub  ssh_host_ed25519_key.pub  ssh_host_rsa_key.pub
ssh_config  sshd_config   ssh_host_dsa_key  ssh_host_ecdsa_key    ssh_host_ed25519_key    ssh_host_rsa_key
root@VM-0-6-rockylinux ssh]# cp sshd_config sshd_config_bak
[root@VM-0-6-rockylinux ssh]# ls
moduli      ssh_config.d  sshd_config_bak  ssh_host_dsa_key      ssh_host_ecdsa_key      ssh_host_ed25519_key      ssh_host_rsa_key
ssh_config  sshd_config   sshd_config.d    ssh_host_dsa_key.pub  ssh_host_ecdsa_key.pub  ssh_host_ed25519_key.pub  ssh_host_rsa_key.pub
[root@VM-0-6-rockylinux ssh]# cat sshd_config
#       $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

# To modify the system-wide sshd configuration, create a  *.conf  file under
#  /etc/ssh/sshd_config.d/  which will be automatically included below
Include /etc/ssh/sshd_config.d/*.conf

# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

# Change to no to disable s/key passwords
#KbdInteractiveAuthentication yes

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in RHEL and may cause several
# problems.
#UsePAM no

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# override default of no subsystems
Subsystem sftp  /usr/libexec/openssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#       X11Forwarding no
#       AllowTcpForwarding no
#       PermitTTY no
#       ForceCommand cvs server
PasswordAuthentication yes

修改好文件之后,我们需要重启一下 sshd 服务:
先通过 systemctl status sshd 命令行查看 sshd 服务的状态;
然后通过 systemctl restart sshd 命令行重启 sshd 服务;
再用 systemctl status sshd 命令行查看 sshd 服务的状态,就会发现 Active 那一行的时间重新开始计算了,就说明重启成功;

[root@VM-0-6-rockylinux ssh]# systemctl status sshd
● sshd.service - OpenSSH server daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
     Active: active (running) since Thu 2024-09-12 23:17:44 CST; 1 day 13h ago
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 764 (sshd)
      Tasks: 1 (limit: 10925)
     Memory: 6.2M
        CPU: 5.097s
     CGroup: /system.slice/sshd.service
             └─764 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

Sep 14 12:26:27 VM-0-6-rockylinux sshd[1063238]: error: kex_exchange_identification: client sent invalid protocol identi>
Sep 14 12:26:27 VM-0-6-rockylinux sshd[1063238]: banner exchange: Connection from 65.49.1.100 port 8293: invalid format
Sep 14 12:28:45 VM-0-6-rockylinux sshd[1063912]: error: kex_exchange_identification: client sent invalid protocol identi>
Sep 14 12:28:45 VM-0-6-rockylinux sshd[1063912]: banner exchange: Connection from 220.196.160.75 port 45164: invalid for>
Sep 14 12:41:26 VM-0-6-rockylinux sshd[1070485]: Connection reset by 198.235.24.78 port 57542 [preauth]
Sep 14 13:01:27 VM-0-6-rockylinux sshd[1076636]: error: kex_exchange_identification: banner line contains invalid charac>
Sep 14 13:01:27 VM-0-6-rockylinux sshd[1076636]: banner exchange: Connection from 91.238.181.23 port 65342: invalid form>
Sep 14 13:06:38 VM-0-6-rockylinux sshd[1078214]: Accepted password for root from 113.84.82.10 port 38420 ssh2
Sep 14 13:06:38 VM-0-6-rockylinux sshd[1078214]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)
Sep 14 13:06:38 VM-0-6-rockylinux sshd[1078214]: pam_lastlog(sshd:session): corruption detected in /var/log/btmp

[root@VM-0-6-rockylinux ssh]# systemctl restart sshd
[root@VM-0-6-rockylinux ssh]# systemctl status sshd
● sshd.service - OpenSSH server daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
     Active: active (running) since Sat 2024-09-14 13:17:37 CST; 3s ago
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 1081621 (sshd)
      Tasks: 1 (limit: 10925)
     Memory: 1.5M
        CPU: 8ms
     CGroup: /system.slice/sshd.service
             └─1081621 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

Sep 14 13:17:37 VM-0-6-rockylinux systemd[1]: Starting OpenSSH server daemon...
Sep 14 13:17:37 VM-0-6-rockylinux sshd[1081621]: Server listening on 0.0.0.0 port 22.
Sep 14 13:17:37 VM-0-6-rockylinux sshd[1081621]: Server listening on :: port 22.
Sep 14 13:17:37 VM-0-6-rockylinux systemd[1]: Started OpenSSH server daemon.


开启了允许服务器远程登录 root 用户:PermitRootLogin yes 之后,再尝试用一下 SSH 工具登录,如果能够登录上去,说明是这个原因导致了 root 用户不能远程登录;如果不是,我们进一步排查当前服务器防火墙的情况。通过命令行查看当前防火墙状态:


通过命令行查看当前防火墙状态:systemctl status firewalld;


出现以下这种情况:Active: inactive (dead)
说明防火墙并未开启,也不是防火墙影响了 root 用户通过 SSH 远程登录,就需要打电话给腾讯云客服寻求帮助;

[root@VM-0-6-rockylinux ~]# systemctl status firewalld
○ firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; preset: enabled)
     Active: inactive (dead)
       Docs: man:firewalld(1)


如果是:Active: active (running)
说明防火墙已经开启,我们需要通过相关的命令行查看防火墙放开了哪些端口,禁止了哪些端口;

[root@VM-0-6-rockylinux ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; preset: enabled)
     Active: active (running) since Sat 2024-09-14 14:22:34 CST; 2s ago
       Docs: man:firewalld(1)
   Main PID: 1106655 (firewalld)
      Tasks: 2 (limit: 10925)
     Memory: 22.7M
        CPU: 342ms
     CGroup: /system.slice/firewalld.service
             └─1106655 /usr/bin/python3 -s /usr/sbin/firewalld --nofork --nopid


防火墙常用的命令如下:

# 启用防火墙 (开机自启动)
systemctl enable firewalld 
# 禁用防火墙 
systemctl disable firewalld 
# 启动防火墙 
systemctl start firewalld 
# 查看防火墙状态
systemctl status firewalld 
# 停止防火墙 
systemctl stop firewalld 
# 重启防火墙
systemctl restart firewalld
# 启用防火墙并启动防火墙 
systemctl enable --now firewalld

# 查看当前防火墙总体状态
firewall-cmd --list-all

# 关闭所有端口
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" reject' 
firewall-cmd --permanent --add-rich-rule='rule family="ipv6" source address="::/0" reject'

# 开启所需端口(不加 --permanent 的话,就是临时生效,重启服务就丢失, --zone 默认值为 public)
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp

# 移除指定的端口
firewall-cmd --permanent --zone=public --remove-port=5443/tcp 

# 重新加载防火墙配置
firewall-cmd --reload

# 显示当前所有 zone 的防火墙状态(默认的是 public)
firewall-cmd --list-all-zones


如果你的防火墙服务并未启用,建议大家养成好的习惯启用起来,也多了一层安全防护,通过以下命令行来设置好当前服务器的防火墙设置,依次执行以下命令;

# 启用防火墙 (开机自启动)
systemctl enable firewalld 
# 启动防火墙
systemctl start firewalld 
# 查看防火墙状态
systemctl status firewalld 
# 罗列防火墙详细配置
firewall-cmd --list-all
# 开启所需端口
firewall-cmd --permanent --add-port=20/tcp
firewall-cmd --permanent --add-port=21/tcp
firewall-cmd --permanent --add-port=22/tcp
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
# 重新加载防火墙配置
firewall-cmd --reload
# 罗列防火墙详细配置
firewall-cmd --list-all


具体执行结果如下:如果这样还不能保证服务器通过 root 用户来远程登录 SSH 的话,就打腾讯云客户电话寻求帮助。

[root@VM-0-6-rockylinux ~]# firewall-cmd --permanent --add-port=20/tcp
success
[root@VM-0-6-rockylinux ~]# firewall-cmd --permanent --add-port=21/tcp
success
[root@VM-0-6-rockylinux ~]# firewall-cmd --permanent --add-port=22/tcp
success
[root@VM-0-6-rockylinux ~]# firewall-cmd --permanent --add-port=80/tcp
success
[root@VM-0-6-rockylinux ~]# firewall-cmd --permanent --add-port=443/tcp
success
[root@VM-0-6-rockylinux ~]# firewall-cmd --reload
success
[root@VM-0-6-rockylinux ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 20/tcp 21/tcp 22/tcp 80/tcp 443/tcp
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 


其他一些防火墙参考资料:https://www.rockylinux.cn/notes/rocky-linux-9-firewall-configuration.html

WordPress 搭建 Step 2:安装 PHP
说明:PHP 是 WordPress 基础支撑服务;
# 我们在 RockyLinux 9.3 上使用 dnf 包管理工具来安装 PHP,使用 dnf 之前,更新一下:
dnf update -y
# 然后安装 EPEL:
dnf install epel-release -y
# 罗列 PHP:
dnf module list php
# 安装最新版本 PHP 8.2:
dnf module install php:8.2 -y
# 安装其他 PHP 模块:
dnf install php-fpm php-curl php-gd php-intl php-mbstring php-soap php-xml php-zip php-mysqli -y

# 查询当前 PHP 服务状态:
systemctl status php-fpm
# 设置开机启动:
systemctl enable php-fpm
# 启动 PHP 服务:
systemctl start php-fpm

# 备注:命令行中的 systemctl status/enable/disable/start/restart *.service,可以直接使用 * ,也可以加上后面的 .service;例如以下两条命令行是一样的效果:
# systemctl status php-fpm
# systemctl status php-fpm.service
WordPress 搭建 Step 3:安装 MariaDB
说明:MariaDB 是 WordPress 基础支撑服务;


通过命令行安装 MariaDB:

# 更新 MariaDB 源:
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash
# 安装 MariaDB 数据库:
dnf install mariadb-server -y
# 查看 MariaDB 状态:
systemctl status mariadb
# 设置 MariaDB 开机自启:
systemctl enable mariadb
# 启动 MariaDB 数据库:
systemctl start mariadb
# 运行数据库安全脚本:
mariadb-secure-installation

# 运行安全脚本之后,会有以下要注意的配置:

# 为 root 用户输入密码,直接回车就无密码;
Enter current password for root (enter for none): 
# 是否切换到 Unix 套接字认证?(简言之,就是用 Linux 服务器 root 用户直接登录数据库,选择 n,单独设置密码登录比较安全)
Switch to unix_socket authentication [Y/n]
# 是否移除匿名用户?(选择 Y,移除匿名用户)
Remove anonymous users? [Y/n]
# 禁止 root 账户远程登录?(选择 Y,禁止 root 账户远程登录)
Disallow root login remotely? [Y/n]
# 是否移除测试数据库及其访问权限?(选择 Y,移除)
Remove test database and access to it? [Y/n]
# 是否重载特权数据表?(选择 Y,重载)
Reload privilege tables now? [Y/n]
问题 2:MariaDB 数据库明明设置了不采用 unix_socket authentication,还是不用密码就能登录。
说明:直接通过 mariadb/mysql 就可以登录数据库,并没有提示需要密码;


就像以下这种情况:

[root@VM-0-7-rockylinux ~]# mariadb
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 19
Server version: 11.5.2-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 


因为我们上边已经选择了不采用 unix_socket authentication,但还是没有密码就登入了数据库,网上找了很多解决方案,就以下这种可以解决;进入 MariaDB 数据库后,在 MariaDB [(none)]> 的后面输入以下内容,记得替换数据库密码,就可以啦!

ALTER USER root@localhost IDENTIFIED VIA mysql_native_password USING PASSWORD("数据库密码"); FLUSH PRIVILEGES;
[root@VM-0-7-rockylinux ~]# mariadb
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 19
Server version: 11.5.2-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> ALTER USER root@localhost IDENTIFIED VIA mysql_native_password USING PASSWORD("数据库密码"); FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.001 sec)

Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> exit
Bye
[root@VM-0-7-rockylinux ~]# mariadb
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)


通过以上操作,最后输入 mariadb 报错,提示要输入密码,就成功的解决这个问题了!我们把数据库设置开机自启和开启数据库服务之后,就先放着,等安装好 WordPress 主程序,再来对接数据库。

WordPress 搭建 Step 4:安装 nginx
说明:nginx 是 WordPress 的 Web 服务器;


我们来安装 nginx Web 服务器:

# 以下命令安装 Nginx
dnf install nginx -y
# 查询 Nginx 状态
systemctl status nginx
# 设置 nginx 开机自启
systemctl enable nginx
# 启动 nginx 
systemctl start nginx


nginx 服务开启之后,就先放着,相关的配置等域名和 WordPress 相关配置到位之后再处理。

WordPress 搭建 Step 5:安装 WordPress
说明:WordPress 的安装很重要。


注意:网上有些教程里面让你下载的是英文版本的 WordPress,里面没有中文资源,无法切换到中文版本,自己去下载官方的语言包更新的话,我觉的这样的操作并不好,测试的时候,感觉有点问题,而且我还担心后续升级是不是也有问题,中文环境还是相对熟悉点,所以说注意下载的 WordPress 中文版本程序。


先去中文 WordPress 站点找到中文版本的下载页面:https://cn.wordpress.org/download,找到具体的下载链接;下载到 /tmp 文件夹,然后解压到 /srv/www/***.com/www 目录底下;为什么搞两个 www 文件名,我个人的理解是 srv 底下的 Web 服务(/srv/www),针对某个网站的 www.***.com 子域名(/srv/www/***.com/www),因为后续可能还会有其他子域名挂载其他的 Web 服务;

# 进入到 tmp 文件夹;
cd /tmp
# 下载最新版本中文 WordPress
wget https://cn.wordpress.org/latest-zh_CN.tar.gz
# 新建一个多层目录,/srv/www/***.com/ 记得替换 *** 成你想要的名称;为何不在后面继续追加 www,是因为后续解压 WordPress 压缩包,会有一个 wordpress 目录,到时候修改成 www 就好;
mkdir -p /srv/www/***.com/
# 将下载的 WordPress 安装程序解压缩到 /srv/www/***.com 
tar -zxvf latest-zh_CN.tar.gz -C /srv/www/***.com
# 进入到 /srv/www/***.com 目录
cd /srv/www/***.com
# 修改 wordpress 目录名称为 www
mv wordpress www
# 最终 WordPress 程序解压到这个目录底下了
/srv/www/***.com/www


注意,这个地方我为何把网站放到 srv/www 目录下,而不是放到 var/www 等其他目录底下,是因为参考了 Linux 官方的文件系统层次结构标准:https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html,其中有针对 srv 的描述:

https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s17.html

3.17. /srv : Data for services provided by this system
Chapter 3. The Root Filesystem

3.17.1. Purpose
/srv contains site-specific data which is served by this system.

Rationale
This main purpose of specifying this is so that users may find the location of the data files for a particular service, and so that services which require a single tree for readonly data, writable data and scripts (such as cgi scripts) can be reasonably placed. Data that is only of interest to a specific user should go in that users' home directory. If the directory and file structure of the data is not exposed to consumers, it should go in /var/lib.

The methodology used to name subdirectories of /srv is unspecified as there is currently no consensus on how this should be done. One method for structuring data under /srv is by protocol, eg. ftp, rsync, www, and cvs. On large systems it can be useful to structure /srv by administrative context, such as /srv/physics/www, /srv/compsci/cvs, etc. This setup will differ from host to host. Therefore, no program should rely on a specific subdirectory structure of /srv existing or data necessarily being stored in /srv. However /srv should always exist on FHS compliant systems and should be used as the default location for such data.

Distributions must take care not to remove locally placed files in these directories without administrator permission. [20]

[20] This is particularly important as these areas will often contain both files initially installed by the distributor, and those added by the administrator.
创建 MariaDB 数据库;
说明:为 WordPress 创建 MariaDB 数据库;


参考官方的数据库设置文档:https://developer.wordpress.org/advanced-administration/before-install/creating-database/
具体操作如下:
注意:一定要保管好上面的 MariaDB 数据库的 root 用户密码和下面的 wordpress 用户密码;

# 登录到 MariaDB 数据库
mariadb -u root -p
# 输入密码
Enter password: 
# 创建数据库 wordpress,设置编码为 UTF-8;
MariaDB [(none)]> CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8;
# 设置数据库用户名 wordpress 和密码 ***;
GRANT ALL ON wordpress.* TO 'wordpress'@'localhost' IDENTIFIED BY '***';
# 更新
MariaDB [(none)]> FLUSH PRIVILEGES;
# 退出
MariaDB [(none)]> exit;


创建和配置好 MariaDB 数据库之后,我们去处理 nginx 配置;

配置 nginx 配置;
说明:为 WordPress 创建 nginx Web 服务器;


nginx 配置注意 /etc/nginx/nginx.conf 通用配置文件,以及针对特定的 Web 服务(WordPress)配置到 /etc/nginx/conf.d/*.conf;在配置 nginx 之前我们为服务准备好域名,然后申请 SSL 证书,建议域名直接就在腾讯云购买:https://console.cloud.tencent.com/domain,然后再去 https://console.cloud.tencent.com/ssl 为你的域名申请 SSL 证书,有免费的 3 个月证书(之前是免费的 1 年),一般申请的时候填写 ***.com 之类的定级域名就好,如果你的 WordPress 是挂的非 www.***.com 之类的二级域名,例如 blog.ifeegoo.com,那就记得填写证书的时候,写 blog.ifeegoo.com;申请通过免费证书之后,记得下载证书,我们采用的 nginx,所以只需要下载 nginx 即可;
里面会有四个证书文件:
***.com_bundle.crt
***.com_bundle.pem
***.com.csr
***.com.key

tencent-cloud-cvm-free-ssl-certificate


我们先直接修改 nginx 的通用配置,直接将 /etc/nginx/nginx.conf 文件内容修改一下;修改之前,记得通过 cat /etc/nginx/nginx.conf 查询下:pid /run/nginx.pid; 类似的一行,记录下这段,后续当 nginx 测试的时候,出错,可能会用得到;
然后养成一个好的习惯对 nginx.conf 做一个备份:cp nginx.conf nginx.conf.bak;
然后再将 nginx.conf 里面的内容直接替换成以下内容:

user              nginx;
worker_processes  auto;
pid               /run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    error_log                      /var/log/nginx/error.log;
    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"';
    access_log                     /var/log/nginx/access.log main;
    sendfile                       on;
    keepalive_timeout              65;
    client_max_body_size           64M;
    server_names_hash_bucket_size  128;
    include                        /etc/nginx/mime.types;
    include                        /etc/nginx/conf.d/*.conf;
    server_names_hash_max_size     512;
    server_tokens                  off;
    client_header_buffer_size      32k;
    large_client_header_buffers    4 32k;
    gzip                           on;
    gzip_disable                   msie6;
    gzip_min_length                1k;
    gzip_comp_level                5;
    gzip_buffers                   4 16k;
    gzip_http_version              1.1;
    gzip_proxied                   any;
    gzip_vary                      on;
    gzip_types                     text/plain text/css text/xml text/javascript text/x-component application/json application/javascript application/xml application/xhtml+xml application/xml+rss application/rss+xml application/atom+xml application/x-font-ttf application/x-web-app-manifest+json font/opentype image/svg+xml image/x-icon;
    fastcgi_buffer_size            64k;
    fastcgi_buffers                4 64k;
    fastcgi_busy_buffers_size      128k;
    fastcgi_temp_file_write_size   256k;
}


然后为我们的 WordPress Web 服务,在 /etc/nginx/conf.d 文件下创建一个 www.***.com.conf 的 nginx 配置文件,文件可以仿照我下面的内容,记得配置你自己的域名,需要修改的地方如下:
# 修改成你从证书机构获得的域名对应的 .crt 证书,路径可以按照我的来,对应上文件即可;
ssl_certificate /etc/ssl/private/www.ifeegoo.com/ssl.bundle.crt;
# 修改成你从证书机构获得的域名对应的 .key 证书,路径可以按照我的来,对应上文件即可;
ssl_certificate_key /etc/ssl/private/www.ifeegoo.com/ifeegoo.com.key;
# 将上面的 *.crt 和 *.key 文件上传到指定位置后,这个 .pem 文件我们通过手动来生成;
openssl dhparam -out /etc/ssl/private/www.ifeegoo.com/dhparam.pem 2048
ssl_dhparam /etc/ssl/private/www.ifeegoo.com/dhparam.pem;
# 配置上你的域名,由于我这里准备采用 www.ifeegoo.com,所以也写上 ifeegoo.com;
server_name ifeegoo.com;
server_name www.ifeegoo.com;
# 配置上你的 WordPress 程序的目录;
root /srv/www/ifeegoo.com/www/;

server {
    listen       80;
    rewrite      ^(.*)$ https://$host$1 permanent;
}

server {
      listen 443 ssl;
      ssl_certificate            /etc/ssl/private/www.ifeegoo.com/ssl.bundle.crt;
      ssl_certificate_key        /etc/ssl/private/www.ifeegoo.com/ifeegoo.com.key;
      ssl_dhparam                /etc/ssl/private/www.ifeegoo.com/dhparam.pem;
      ssl_ciphers                'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4';
      ssl_prefer_server_ciphers  on;
      ssl_protocols              TLSv1.3 TLSv1.2;
      ssl_session_cache          shared:SSL:10m;
      ssl_session_timeout        10m;
      return 500;
}

server {
    listen                     80;
    listen                     443 ssl;
    server_name                ifeegoo.com;
    server_name                www.ifeegoo.com;
    root                       /srv/www/ifeegoo.com/www/;
    index                      index.html index.htm index.php;
    keepalive_timeout          70;
    error_page                 502 /error_pages/502.html;
    error_page                 503 /error_pages/503.html;
    error_page                 504 /error_pages/504.html;
    error_page                 403 /error_pages/403.html;
    error_page                 404 /error_pages/404.html;
    error_page                 500 /error_pages/500.html;
    add_header                 Strict-Transport-Security max-age=31536000;
    add_header                 X-Content-Type-Options nosniff;
    rewrite                    ^.*/files/(.*)$ /wp-includes/ms-files.php?file=$1 last;

    if (!-e $request_filename) {
        rewrite  ^.+?(/wp-.*) $1 last;
        rewrite  ^.+?(/.*\.php)$ $1 last;
        rewrite  ^ /index.php last;
    }

    location ~ ^/.+\.php {
        fastcgi_index            index.php;
        fastcgi_split_path_info  ^(.+\.php)(.*)$;
        fastcgi_param            SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param            PATH_INFO $fastcgi_path_info;
        fastcgi_param            QUERY_STRING $query_string;
        fastcgi_param            REQUEST_METHOD $request_method;
        fastcgi_param            CONTENT_TYPE $content_type;
        fastcgi_param            CONTENT_LENGTH $content_length;
        fastcgi_param            SCRIPT_NAME $fastcgi_script_name;
        fastcgi_param            REQUEST_URI $request_uri;
        fastcgi_param            DOCUMENT_URI $document_uri;
        fastcgi_param            DOCUMENT_ROOT $document_root;
        fastcgi_param            SERVER_PROTOCOL $server_protocol;
        fastcgi_param            GATEWAY_INTERFACE CGI/1.1;
        fastcgi_param            SERVER_SOFTWARE nginx/$nginx_version;
        fastcgi_param            REMOTE_ADDR $remote_addr;
        fastcgi_param            REMOTE_PORT $remote_port;
        fastcgi_param            SERVER_ADDR $server_addr;
        fastcgi_param            SERVER_PORT $server_port;
        fastcgi_param            SERVER_NAME $server_name;
        fastcgi_param            REDIRECT_STATUS 200;
        fastcgi_param            PHP_VALUE open_basedir=$document_root:/tmp/:/proc/:/var/lib/php-fpm/;
        fastcgi_pass             127.0.0.1:9000;
    }

    location ~* \.(js|css|jpg|gif|png|bmp|swf)$ {
        expires  30d;
    }
}


我们配置好以上两块 nginx 配置文件之后,可以通过命令行 nginx -t && nginx -s reload 来测试配置正确性(只是一定程度的配置正确性,没有报错并不能说明完全没有错)和重载配置,不放心的话,可以再重启一下 nginx,systemctl restart nginx。如果有问题,就按照提示的问题一步步来解决,如果提示没有问题,接下来我们关联一下我们的域名和服务器。

域名和服务器 IP 的关联配置
说明:域名解析是你 WordPress 站点访问的基础;


我们获取到当前服务器的公网 IP 地址之后,要去当前域名管理面板去解析一下,例如我添加的两条域名解析记录:一条 A 记录,一条 CNAME 记录。
主机记录 记录类型 记录值
@ A “公网 IP 地址”
www CNAME ***.com
做完了域名解析之后,不会马上生效,需要等待一些时间,接下来我们去处理 WordPress 配置。

WordPress 配置
说明:WordPress 的配置是安装前的重要一步;


我们去到 WordPress 的安装根目录,看是否有一个 wp-config-sample.php 的文件,然后将文件改名为 wp-config.php

# 修改文件名称
mv wp-config-sample.php wp-config.php
# 执行以下命令,获得 WordPress 官方生成的秘钥
curl -s https://api.wordpress.org/secret-key/1.1/salt/
# 执行以上命令,你会拿到以下字符串:
define('AUTH_KEY',         '***');
define('SECURE_AUTH_KEY',  '***');
define('LOGGED_IN_KEY',    '***');
define('NONCE_KEY',        '***');
define('AUTH_SALT',        '***');
define('SECURE_AUTH_SALT', '***');
define('LOGGED_IN_SALT',   '***');
define('NONCE_SALT',       '***');
# 直接将上面这一段放到 wp-config.php 指定位置覆盖或者替换;

# 修改重要的数据库配置:数据库名、数据库用户、数据库密码、其他几项默认;

// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpress' );

/** Database username */
define( 'DB_USER', 'wordpress' );

/** Database password */
define( 'DB_PASSWORD', 'password' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );

/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );


那么一切准备就绪之后,我们去通过指定的域名去访问 WordPress,如果你发现有 nginx 的 502 Bad Gateway 错误,那么可以尝试以下方式来修复。

问题 3:nginx 的 502 Bad Gateway 错误
说明:以下是其中的一种可能的原因;


一般出现上面的问题,我们需要排查 PHP 服务:

# 查看当前 PHP 服务状态
systemctl status php-fpm

● php-fpm.service - The PHP FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
     Active: active (running) since Sat 2024-09-14 20:00:55 CST; 1 day 3h ago
   Main PID: 1342186 (php-fpm)
     Status: "Processes active: 0, idle: 5, Requests: 41, slow: 0, Traffic: 0req/sec"
      Tasks: 6 (limit: 10925)
     Memory: 19.5M
        CPU: 3.301s
     CGroup: /system.slice/php-fpm.service
             ├─1342186 "php-fpm: master process (/etc/php-fpm.conf)"
             ├─1342187 "php-fpm: pool www"
             ├─1342188 "php-fpm: pool www"
             ├─1342189 "php-fpm: pool www"
             ├─1342190 "php-fpm: pool www"
             └─1342191 "php-fpm: pool www"

Sep 14 20:00:55 VM-0-6-rockylinux systemd[1]: Starting The PHP FastCGI Process Manager...
Sep 14 20:00:55 VM-0-6-rockylinux systemd[1]: Started The PHP FastCGI Process Manager.

# 如果正常,就查看当前 PHP 服务的 9000 端口是否有被监听
netstat -tuln

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN     
tcp6       0      0 :::3306                 :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
udp        0      0 127.0.0.1:323           0.0.0.0:*                          
udp6       0      0 ::1:323                 :::*

# 很明显,我们没有看到 9000 端口,我们找到 /etc/php-fpm.d/www.conf 文件,然后找到里面这行配置:
listen = /run/php-fpm/www.sock

# 然后用 ; 将其注释掉,追加一行:listen = 127.0.0.1:9000

;listen = /run/php-fpm/www.sock
listen = 127.0.0.1:9000

# 保存,退出;
# 重载 PHP 配置,重启 PHP 服务
systemctl reload php-fpm
systemctl restart php-fpm      

# 再查询下端口情况,发现已经有 9000 端口的监听了;
netstat -tuln

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN     
tcp6       0      0 :::3306                 :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
udp        0      0 127.0.0.1:323           0.0.0.0:*                          
udp6       0      0 ::1:323                 :::*               


再去访问一下,如果你发现如果你能够访问到此页面,那就离成功只有一步之遥了!

wordpress-installation-configuration


把 WordPress 配置好了之后,登录进去,先别慌着进行下一步,我们尝试一个非常重要的东西:重启下服务器!用来验证当前各个服务是否都都配置好了开机自动启动,如果没有,强烈建议你详细排查下,确保这一步很重要!当你服务器出现异常需要重启的时候,这些服务就自己启动起来了,不需要你自己手动去启动,网站就运行起来了;

WordPress 多重数据备份
说明:数据备份非常重要。


针对个人的小博客网站,并不是很要求高实时性的数据备份,我建议采取三种数据备份的方法相结合即可:
1、备份 WordPress 目录下的所有文件以及 MariaDB 数据库;
说明:可以采用定时器策略,执行定时脚本来打包 WordPress 目录底下的所有文件和导出 MariaDB 数据库,自己手动下载保存备份,并且选择删除哪些备份文件;
2、采用腾讯云的定时“磁盘快照”策略,来进行整个系统数据备份;
说明:当你初始配置好 WordPress 以及第一步之后,建议做一个永久的初始“磁盘快照”的备份;以便出现问题的时候,还可以恢复到当时正常的配置;
3、采用腾讯云新推出的“数据备份点”,来进行整个系统数据备份;
说明:具体参见 https://cloud.tencent.com/document/product/362/73592


我们先来编写 Shell 命令来执行 WordPress 目录下文件的打包和 MariaDB 数据库的导出,将以下命令复制并生成 backup.sh 文件存到对应的文件夹下(注意新建对应的目录):/data/backup/www/ifeegoo.com/www/,实际命令里面的各种目录路径和用户名密码记得修改成自己的。

#!/bin/bash

# 备份文件保存路径和前缀
TOTAL_BACKUP_DIR="/data/backup/www/ifeegoo.com/www"
WORDPRESS_DIR="/srv/www/ifeegoo.com/www"
DATABASE_BACKUP_FILE_PREFIX="mariadb_backup_"
WORDPRESS_BACKUP_FILE_PREFIX="wordpress_backup_"

# MariaDB 数据库名称、用户名、密码;
DATABASE_NAME="wordpress"
MARIADB_USERNAME="root"
# 注意如果数据库密码里面包含特殊字符,记得转义,例如 $,要写成 \$;
MARIADB_PASSWORD="***"

# 获取当前日期作为备份文件的时间标记
DATE=$(date +"%Y%m%d%H%M%S")

# 构建完整的 WordPress 文件备份文件名和 MariaDB 数据库备份文件名
WORDPRESS_BACKUP_FILENAME="$TOTAL_BACKUP_DIR/$WORDPRESS_BACKUP_FILE_PREFIX$DATE.tar.gz"
DATABASE_BACKUP_FILENAME="$TOTAL_BACKUP_DIR/$DATABASE_BACKUP_FILE_PREFIX$DATE.sql.gz"

# 打包 WordPress 文件夹
tar -zcvf "$WORDPRESS_BACKUP_FILENAME" $WORDPRESS_DIR

# 检查上面的 WordPress 文件夹打包命令是否执行成功;
if [ $? -eq 0 ]; then
echo "WordPress 文件夹打包成功!"
else
echo "WordPress 文件夹打包失败,请核对相关错误日志。"
fi

# MariaDB 数据库备份
mariadb-dump -u $MARIADB_USERNAME -p$MARIADB_PASSWORD $DATABASE_NAME | gzip > "$DATABASE_BACKUP_FILENAME"

# 检查上面的 MariaDB 数据库备份命令是否执行成功;
if [ $? -eq 0 ]; then
echo "MariaDB 数据库导出成功!"
else
echo "MariaDB 数据库导出失败,请核对相关错误日志。"
fi


单次执行以上 backup.sh 命令,看看是否成功生成了 WordPress 文件夹压缩包和 MariaDB 数据库压缩包,如果有问题就根据报错去调试,在本地可以用 WebStorm 等第三方 IDE 进行调试,会一定程度提示你各种错误。确认以上 backup.sh 没有问题的话,我们来创建定时器。
说明:以上备份 Shell 命令后续可以根据实际情况再优化一下了,例如只保留 N 天以内的备份数据,其余的删除掉,减少空间的数据占用。

# 打开 crontab 编辑里面的定时器
crontab -e
# 追加以下内容(*/1 * * * *:每分钟执行,用于测试):
*/1 * * * * bash -c "sh /data/backup/www/ifeegoo.com/www/backup.sh"
# 重启 crontab 服务
systemctl restart crond
# 上面设置每分钟执行快速确认没有问题的话,就改成以下定时频率,每天 02:00 开始;
0 2 * * * bash -c "sh /data/backup/www/ifeegoo.com/www/backup.sh"


如果你不知道如何更好的设置 crontab 和不知道是否设置正确,有以下三个很有用的网站帮助你:
# crontab 规则配置实时生成说明
https://crontab.guru
# crontab 具体执行的逻辑示例
https://tool.lu/crontab
# crontab 表达式生成器
https://www.bejson.com/othertools/cron/
说明:一般 crond 都是随着系统预置和开机自启动的,所以不用担心重启了服务器就不用生效,可以通过命令行查看:里面第三行,里面有两个 enable,第一个 enable 就是当前已经启动了。

[root@VM-0-6-rockylinux www]# systemctl status crond
● crond.service - Command Scheduler
     Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; preset: enabled)
     Active: active (running) since Mon 2024-09-16 13:36:56 CST; 6s ago
   Main PID: 470309 (crond)
      Tasks: 41 (limit: 10924)
     Memory: 309.8M
        CPU: 173ms
     CGroup: /system.slice/crond.service
             ├─  4759 /usr/local/qcloud/YunJing/YDLive/YDLive
             ├─  4786 /usr/local/qcloud/stargate/bin/sgagent -d
             ├─  4818 barad_agent
             ├─  4825 barad_agent
             ├─  4826 barad_agent
             ├─  5604 /usr/local/qcloud/YunJing/YDEyes/YDService
             └─470309 /usr/sbin/crond -n


利用 crontab 定时执行 Shell 命令做好以上自动化备份机制之后,我们在腾讯云里面做一个“定时磁盘快照”,先设置磁盘快照策略:我们设置每天 03:00 自动化执行磁盘快照,因为我们上面自己设置的定时备份机制在每天的 02:00。另外我们先设置保留 14 天,然后关联相关的硬盘即可。

tencent-cvm-scheduled-disk-snapshot-policy


对于新手来说,采用上面的自己创建的备份机制以及腾讯云自带的“磁盘快照”机制进行数据备份即可,如果你还想做一个三保险,那可以采用腾讯云新出的数据备份点,买 14 个点(两周)的数据备份即可,也不贵。可以手动去创建备份点,如果不是手动的话,是会在每天随机时间来创建一个数据备份点,最多 14 个,满了会删除最旧的一个数据备份点。同时数据备份点还可以手动转化成磁盘快照。

tencent-cvm-data-backup-point

WordPress 搭建 Step 5:相关配置
说明:使用 WordPress 之前做好相关配置。


我们先安装几个重要的插件,一个是反垃圾评论插件,这个一般都是默认随 WordPress 安装的,WordPress 官方出品,只是没有启用而已,我们去到 WordPress 管理后台 – 插件,可以看到:Akismet 反垃圾评论:垃圾评论保护。我们点击“启用”:点击“选择 Akismet 计划”,然后会跳转到 Akismet 网站,建议我们先去 wordpress.com 注册一个账号,回过头来这个网站登录即可,后续 wordpress.com 网站账户还有其他用处。

wordpress-plugin-installation

wordpress-akismet-setup-step-1


接着选择 Personal 个人使用:

wordpress-akismet-setup-step-2


勾选相关配置:

wordpress-akismet-setup-step-3

wordpress-akismet-setup-step-4

wordpress-akismet-setup-step-5

wordpress-akismet-setup-step-6

wordpress-akismet-setup-step-7


填写相关信息,支付之后(免费),最终获得 API 秘钥,复制一下填写到 WordPress 后台配置中即可。


我们安装另外一个插件:No Category Base,这个插件的作用是让你的 URL 精简,移除你 URL 中的 /category/。

wordpress-plugin-no-category-base-installation

问题 4:需要输入 FTP 登录凭据才能继续
说明:WordPress 文件读写常见问题之一。


我们去 WordPress 管理后台插件市场检索:No Category Base 插件,找到之后点击“立即安装”,然后可能会弹出一下提示框,提示输入链接信息,需要输入 FTP 登录凭据才能继续,主机名/FTP 用户名/FTP 密码之类的,我们这里先取消掉不管,出现这个问题一般是由于 WordPress 的针对文件的操作模式设置的问题。

wordpress-plugin-installation-needs-ftp-permission


出现以上情况,是因为当前没有给 WordPress 设置好文件系统访问方法,可以在 wp-config.php 文件中追加以下参数定义:
define(‘FS_METHOD’,’direct’);
FS_METHOD 有三种参数值:
direct:这是最简单的方法,它使用 PHP 的文件操作函数(如 file_put_contents、file_get_contents 等)直接读写文件。通常,这种方法只在文件系统权限被正确配置且安全的情况下使用。
ftpext:这种方法通过 FTP 连接到服务器,并使用 FTP 函数进行文件操作。它通常用于那些不能直接访问文件系统的环境,例如共享主机。你需要提供 FTP 连接的相关信息,如主机名、用户名、密码等。
ssh2:这种方法通过 SSH2 连接到服务器,使用 SSH2 函数进行文件操作。类似于 FTP 方法,它也用于那些不能直接访问文件系统的情况。需要提供 SSH 连接的相关信息。


配置好了之后,再操作安装插件,就不会提示需要输入 FTP 登录凭据才能继续,但是可能又会出现提示:安装失败,无法创建目录;这种错误一般都是由于读写权限异常导致的。这里有一个相关重点 WordPress 的读写权限值推荐:

wordpress-file-permission-examples

问题 5:安装失败,无法创建目录,或无读写权限。
说明:WordPress 文件权限读写,常见问题之一。

wordpress-plugin-installation-failure-cannot-create-folder


同时我们可以用 WordPress 自带的工具:站点健康,通过检查,在“状态”一栏中,发现提示“无法创建升级目录”的详细错误信息;同时在“信息” – “文件系统权限”中显示不具备可写的一些目录。

wordpress-tool-site-health-check-1

wordpress-tool-site-health-check-2

wordpress-tool-site-health-check-3


我们登录到系统中去查看当前几个目录的写入权限:
看了下,都是 drwxr-xr-x,明明当前所有者是可写的呢?这个地方我们目前登录的是 root 用户,我们需要找到和 WordPress 这个程序相关的用户;
d:表述当前为目录
rwx:(所有者) 可读、可写、可执行(7)
r-x:(同组用户)可读、可执行(5)
r-x:(其他用户)可读、可执行(5)
drwxr-xr-x 5 1006 1006 4096 Sep 16 15:48 www
drwxr-xr-x 9 1006 1006 4096 Sep 11 03:00 wp-admin
drwxr-xr-x 5 1006 1006 4096 Sep 16 16:14 wp-content
drwxr-xr-x 30 1006 1006 12288 Sep 11 03:00 wp-includes


由于 WordPress 是 PHP 服务支撑的,我们通过 ps aux | grep php-fpm 命令查看下当前 php-fpm 运行情况;

# ps aux | grep php-fpm
root      549314  0.0  1.6  88928 30124 ?        Ss   15:41   0:00 php-fpm: master process (/etc/php-fpm.conf)
apache    549328  0.0  3.3 199728 59100 ?        S    15:41   0:05 php-fpm: pool www
apache    549329  0.0  3.4 199608 61228 ?        S    15:41   0:05 php-fpm: pool www
apache    549330  0.0  3.4 199676 61628 ?        S    15:41   0:06 php-fpm: pool www
apache    549331  0.0  3.4 199776 62064 ?        S    15:41   0:06 php-fpm: pool www
apache    549332  0.0  3.4 199760 61296 ?        S    15:41   0:06 php-fpm: pool www
apache    549392  0.0  3.4 199932 61344 ?        S    15:41   0:05 php-fpm: pool www
apache    551535  0.0  3.4 199784 61764 ?        S    15:48   0:04 php-fpm: pool www
root      647424  0.0  0.1   6408  2304 pts/0    S+   17:59   0:00 grep --color=auto php-fpm

# id apache
uid=48(apache) gid=48(apache) groups=48(apache)


我们可以看到当前 php-fpm 服务都是 “apache” (我不太清楚为什么此处默认的是 apache,我没有用 apache 的 Web 服务器,也不知道 PHP 和 apache 基金会有关系?)用户来运行的,因此我们通过 id apache 命令来查一下 apache 用户所属的组;
注意:有些网上教程说后面 pool www 里面的 www 才是用户,那我假设当前用户是 www,但是我通过 id www 命令,是找不到这个用户的。


我们针对当前需要针对 PHP 服务的用户 apache 开放 755 权限,当前几个目录其实已经是 755 权限了,我们将所属用户改成 apache 就好。

# WordPress 根目录
chown apache www
# wp-includes 目录
chown apache www/wp-includes
# wp-admin 目录
chown apache www/wp-admin
# wp-admin/js 目录
chown apache www/wp-admin/js
# wp-content 目录
chown apache www/wp-content
# wp-content/themes 目录
chown apache www/wp-content/themes
# wp-content/plugins 目录
chown apache www/wp-content/plugins

以下两个目录初始安装的时候可能不存在,可以新建一下
# wp-content/uploads 目录
chown apache www/wp-content/uploads
# wp-content/upgrade 目录
chown apache www/wp-content/upgrade


我们再回过头到 WordPress 里面的工具:站点健康 – 信息 – 文件系统权限,这个时候发现基本上都处于可写的状态了,然后再去安装插件也没有太大问题了。注意已安装的插件尽量避免设置自动更新,防止出现兼容性问题,后续手动更新即可。

wordpress-tool-site-health-check-4


另外我们设置一下 WordPress 发表文章的链接地址,这个完全看个人的习惯以及使用的一些第三方主题的设置了,我个人不喜欢复杂冗长的 URL,所以选择 https://***.com/***.html 格式来展示文章 URL,我不喜欢用 https://***.com/***/ 来表示文章 URL,虽然很多人推荐这样做,是因为对 SEO 更又好,我是非常不认同这种作为单个页面文章的 URL 的,单个页面就用 .html 结尾,一目了然,目录就用目录,这样顺其自然,其实 SEO 也差不了太多。

wordpress-permalink-settings

问题 6:上传的文件大小超过 php.ini 文件中定义的 upload_max_filesize 值。
说明:安装主题,上传文件,发表文章经常会报错。


当我们安装主题,上传文件,发表文章经常会报错:上传的文件大小超过 php.ini 文件中定义的 upload_max_filesize 值。是因为默认的 PHP 默认配置的上传的最大文件大小比较小,去修改一下。

# 查找 php.ini 文件所在位置
whereis php.ini
php.ini: /etc/php.ini

# 修改 /etc/php.ini,调大以下两个参数,一个是上传的最大文件大小,另外一个是整个请求正文的大小。
upload_max_filesize = 64M
post_max_size = 100M

# 重启 PHP 服务
systemctl restart php-fpm


从此基本上可以安心创作了,做好服务器安全和数据备份工作。运维过程中发现其他问题再来次更新,祝你早日搭建好 WordPress 站点,加油!


温馨提醒:可以在此节点再次通过腾讯云做一次永久保存的磁盘快照,留作数据备份,以备不时之需。

WordPress 相关问题记录。
说明:各种运营过程中出现的问题。
WordPress 相关配置。
说明:各种运营过程中出现的问题。


1. 移除文件上传目录的年月 URL,例如 /upload/2014/09/file.* 改成 /upload/file.*。


我们只需要去到管理后台:设置 – 媒体 – 上传 – (取消勾选)以年—月目录形式组织上传内容,然后保存即可。


2. WordPress 网站统计功能。


推荐大家集成三家的网站统计:百度(虽然不喜欢,但是毕竟是国内第一大引擎,还是有必要集成统计数据的),另外就是谷歌和微软,这两家在 WordPress 都有相关的官方插件:Site Kit by Google 和 Microsoft Clarity 下载安装启用,登录激活即可,很方便。


3. WordPress 播客插件。


目前正在尝试这两个插件:Seriously Simple Podcasting 和 选择 Blubrry PowerPress,具体效果等时候后来更新。

打赏
本博客所有文章如无特别注明均为原创。复制或转载请以超链接形式注明转自ifeegoo,原文地址《在 腾讯云 RockyLinux 9.3 上用 PHP、MariaDB、nginx 安装 WordPress
上一篇: « 下一篇:
Copyright © ifeegoo Time is limited, less is more! / 粤ICP备15109713号 / Theme by Hang & Ben / WordPress / 知识共享许可协议