在 HMS VPS 上使用 Bedrock 实现 WordPress GitOps
本指南将介绍如何在 HostMyServers VPS 上托管 WordPress 网站,并借助 Bedrock(Roots 提供的 WordPress 脚手架)以 GitOps 方式进行管理。您的 Git 仓库将成为唯一可信源:WordPress 核心、插件和主题都以代码形式声明并纳入版本控制,然后在每次 git push 时自动部署到您的 VPS。
VPS 为您提供 root 权限、SSH 访问以及对整套软件栈(Nginx、PHP-FPM、MariaDB)的完全控制,这是这种部署方式所必需的,而共享主机无法提供这些条件。
传统的 WordPress 会将代码(核心、插件、主题)、配置(wp-config.php)和数据(上传文件)混杂在同一个目录中,并且通过管理后台进行更新。这使得版本控制和环境复现变得困难。Bedrock 带来了以下改进:
- 使用 Composer 将 WordPress 核心、插件和主题当作依赖项管理(版本锁定在
composer.lock中) - 通过环境变量进行配置(
.env文件),不在 Git 中存放任何密钥 - 按环境区分配置文件(开发、预发布、生产)
- 更安全的目录结构:Web 服务器只暴露
web/目录 - 在生产环境中禁用后台修改文件的功能(
DISALLOW_FILE_MODS)
订购 HostMyServers VPS
本指南适用于 HostMyServers VPS。请根据您的流量情况选择合适的方案:
- NVMe VPS - 性价比极高,适合搭建展示型网站或博客
- Performance VPS - 推荐用于 WooCommerce 商城和高流量网站
| 用途 | vCPU | 内存 | 存储 |
|---|---|---|---|
| 展示型网站 / 博客 | 1-2 | 2 GB | 20 GB NVMe |
| 中等流量、多站点 | 2-4 | 4 GB | 40 GB NVMe |
| WooCommerce / 高流量 | 4+ | 8 GB+ | 80 GB NVMe+ |
下单时,请选择 Ubuntu 24.04 LTS 或 Debian 12 作为操作系统。VPS 交付后,IP 地址和 root 登录凭据会通过邮件发送给您,同时也可以在您的 HostMyServers 客户空间中查看。
对于多个高流量站点,同样的流程也适用于 Eco 和 Performance 专用服务器。
将 GitOps 原则应用于 WordPress
| 元素 | 存放位置 | 是否纳入 Git 版本控制? |
|---|---|---|
| WordPress 核心、公共插件和主题 | composer.json + composer.lock | 是(声明 + 精确版本) |
| 您自己开发的主题和插件 | web/app/themes/、web/app/plugins/ | 是(源代码) |
| 配置(常量、环境) | config/ | 是 |
| 密钥(密码、密钥、盐值) | 每台服务器上的 .env | 否 |
| 媒体文件(上传内容) | 服务器上的 web/app/uploads/ | 否(需要备份) |
| 内容(文章、页面、设置) | MySQL/MariaDB 数据库 | 否(需要备份) |
生命周期变为:
- 您在本地修改代码或更新依赖
- 您提交并推送到
main分支 - CI 流水线安装依赖,并在服务器上部署一个新的发布版本(release)
- 如果出现问题,您可以回退到上一个发布版本(
git revert或切换符号链接)
数据库和媒体文件属于数据,而非代码,不由 Git 管理:请建立定期备份机制(wp db export、备份 shared/uploads 目录、VPS 快照)。
前提条件
在您的开发机器上:
- Git
- PHP ≥ 8.1(推荐 8.3)以及 Composer 2
- 一个用于托管仓库的 GitHub(或 GitLab)账号
在您的 HMS VPS(Ubuntu 24.04 LTS / Debian 12)上:
- root 用户或具有 sudo 权限的用户的 SSH 访问权限
- 一台已加固的 VPS(非 root 用户、SSH、防火墙):参见加固服务器安全
- 一个域名,其 DNS
A记录指向该 VPS 的 IP 地址
在本指南中,composer install 由 CI 流水线执行。VPS 上只接收已经准备好的文件:它既不需要 Composer,也不需要 Git,也不需要访问软件包仓库。
步骤 1:在本地创建 Bedrock 项目
-
创建项目:
composer create-project roots/bedrock mon-sitecd mon-site -
了解目录结构:
mon-site/├── composer.json # 声明 WordPress 核心、插件和主题├── composer.lock # 已安装的精确版本├── .env.example # 配置模板├── wp-cli.yml # 告知 WP-CLI WordPress 所在位置(web/wp)├── config/│ ├── application.php # 主配置(取代 wp-config.php)│ └── environments/│ ├── development.php│ └── staging.php├── vendor/ # Composer 依赖(未纳入版本控制)└── web/ # Web 服务器根目录(document root)├── app/ # 相当于 wp-content│ ├── mu-plugins/│ ├── plugins/│ ├── themes/│ └── uploads/├── wp/ # WordPress 核心(未纳入版本控制)├── wp-config.php└── index.php信息使用 Bedrock 时,管理后台地址为
https://your-domain.com/wp/wp-admin,且wp-content被web/app取代。 -
基于模板创建本地
.env文件:cp .env.example .env.envDB_NAME='wordpress_dev'DB_USER='wordpress_user'DB_PASSWORD='local_password'DB_HOST='localhost'DB_PREFIX='wp_'WP_ENV='development'WP_HOME='http://mon-site.test'WP_SITEURL="${WP_HOME}/wp"AUTH_KEY='generateme'SECURE_AUTH_KEY='generateme'LOGGED_IN_KEY='generateme'NONCE_KEY='generateme'AUTH_SALT='generateme'SECURE_AUTH_SALT='generateme'LOGGED_IN_SALT='generateme'NONCE_SALT='generateme' -
为每个环境生成独立的密钥和盐值:
for k in AUTH_KEY SECURE_AUTH_KEY LOGGED_IN_KEY NONCE_KEY AUTH_SALT SECURE_AUTH_SALT LOGGED_IN_SALT NONCE_SALT; doecho "$k='$(openssl rand -base64 48 | tr -d '\n')'"done将输出结果复制到您的
.env文件中,替换掉generateme所在的行。您也可以使用 Roots 生成器。
若要在本地运行站点,可使用您喜欢的工具(DDEV、Lando、Laravel Valet、Docker 等),并将 Web 根目录指向 web/ 文件夹。
步骤 2:使用 Composer 管理插件和主题
Bedrock 已预先配置好 WPackagist,这是 WordPress.org 官方目录中所有插件和主题的 Composer 镜像。
-
安装插件或主题:
composer require wpackagist-plugin/wordpress-seocomposer require wpackagist-plugin/wp-mail-smtpcomposer require wpackagist-theme/twentytwentyfive软件包名称对应 WordPress.org 的 slug(
https://wordpress.org/plugins/<slug>/)。 -
更新依赖:
# 根据 composer.json 的约束更新所有内容composer update# 仅更新 WordPress 核心composer update roots/wordpress --with-all-dependencies# 查看可用的更新composer outdated -
删除插件:
composer remove wpackagist-plugin/wp-mail-smtp
composer.lock 文件确保生产环境安装的版本与本地测试过的版本完全一致,因此必须始终纳入版本控制。
付费或私有插件
付费插件不在 WPackagist 上。有两种解决方案:
-
推荐做法:使用发布方提供的 Composer 仓库(ACF Pro、Gravity Forms、WPML 等均提供此类仓库),并将认证密钥存放在
auth.json(未纳入版本控制)以及 CI 的密钥管理中。 -
备选方案:在
.gitignore中添加例外规则,将插件直接纳入仓库版本控制:.gitignoreweb/app/plugins/*!web/app/plugins/.gitkeep!web/app/plugins/mon-plugin-premium
您自己的主题(位于 web/app/themes/)默认会被纳入版本控制。
步骤 3:调整配置
通用配置位于 config/application.php 中,各环境的覆盖配置位于 config/environments/<WP_ENV>.php 中。默认情况下,Bedrock:
- 在生产环境中禁用文件编辑器以及从管理后台安装/更新插件的功能(
DISALLOW_FILE_MODS) - 在
development环境中允许上述操作 - 在生产环境中隐藏 PHP 错误信息
这一行为正是 GitOps 的核心所在:在生产环境中,任何代码修改都必须通过 Git 完成。如果某个插件显示「有可用更新」,请在本地使用 Composer 完成更新、测试,然后提交。
为所有环境添加一个常量的示例:
Config::define('WP_POST_REVISIONS', 10);
Config::define('WP_MEMORY_LIMIT', '256M');