本文约 3,142 字,预计阅读 8 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:Bedrock 想解决的三个老问题
WordPress 默认结构有几个公认的别扭之处:
- 核心代码暴露在 Web 根目录,任何人都知道你跑的是 WordPress;
wp-config.php里写死数据库密码,改环境要改文件;- 没有统一的依赖管理,插件版本靠后台点更新。
Bedrock 用一套约定把这三件事都改了。但它不是”升级版 WordPress”,而是一套开发规范,是否采用要看你的项目形态。
原理分析:Bedrock 做了什么改造
| 项目 | 默认结构 | Bedrock |
|---|---|---|
| 核心位置 | 站点根目录 | web/wp/(Web 根是 web/) |
| 配置 | wp-config.php |
.env + config/application.php |
| 依赖 | 后台更新 | Composer |
| 内容目录 | wp-content/ |
web/app/ |
| 环境区分 | 无 | 通过 WP_ENV 常量 |
核心收益是:Web 服务器只暴露 web/ 目录,核心代码和 .env 都在 Web 根之外,即使 Nginx 配错也不会被下载到。
保姆级实操
第一步:创建项目
composer create-project roots/bedrock mimangfei-site
cd mimangfei-site
第二步:目录结构
mimangfei-site/
├── config/
│ ├── application.php # 主配置,读 $_ENV
│ └── environments/
│ ├── development.php
│ ├── staging.php
│ └── production.php
├── web/
│ ├── app/ # 原 wp-content
│ │ ├── mu-plugins/
│ │ ├── plugins/
│ │ ├── themes/
│ │ └── uploads/
│ ├── wp/ # WordPress 核心
│ ├── index.php
│ └── wp-config.php
├── .env # 环境变量(不提交)
├── .env.example
├── composer.json
└── wp-cli.yml
第三步:配置 .env
DB_NAME=wordpress
DB_USER=wpuser
DB_PASSWORD='强密码'
DB_HOST=localhost
WP_ENV='production'
WP_HOME='https://mimangfei.com'
WP_SITEURL='https://mimangfei.com/wp'
# 安全密钥,从 https://roots.io/salts.html 生成
AUTH_KEY='...'
SECURE_AUTH_KEY='...'
LOGGED_IN_KEY='...'
NONCE_KEY='...'
AUTH_SALT='...'
SECURE_AUTH_SALT='...'
LOGGED_IN_SALT='...'
NONCE_SALT='...'
第四步:Nginx 配置
Web 根目录指向 web/:
server {
listen 80;
server_name mimangfei.com;
root /var/www/mimangfei-site/web; # 注意是 web 而不是项目根
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
# 阻止访问核心目录之外的敏感文件
location ~ ^/wp/(wp-admin|wp-includes)/ { deny all; }
}
第五步:安装插件与主题
composer require wpackagist-plugin/wordpress-seo
composer require wpackagist-theme/twentytwentyfour
第六步:环境区分
config/environments/production.php:
<?php
Config::define('WP_DEBUG', false);
Config::define('DISALLOW_FILE_MODS', true);
Config::define('AUTOMATIC_UPDATER_DISABLED', true);
Config::define('WP_POST_REVISIONS', 5);
development.php 则打开 WP_DEBUG、WP_DEBUG_DISPLAY、SAVEQUERIES。
第七步:WP-CLI
项目自带 wp-cli.yml:
path: web/wp
所以在项目根目录直接执行 wp plugin list 就能生效。
代价与不适合的场景
代价:
- 后台更新被禁用(生产环境
DISALLOW_FILE_MODS=true),装插件必须走 Composer,协作同事要学新流程; - 部分插件假设
wp-content路径固定,硬编码路径的插件会出问题; - 主流主机商(尤其共享虚拟主机)无法把 Web 根指向子目录,Bedrock 用不了;
- 迁移、备份工具普遍按默认结构写,需要手工适配。
不适合: 单站点、虚拟主机、非技术同事维护、依赖大量商业插件的项目。
适合: 多环境(本地/测试/生产)、团队协作、有 CI/CD、重视密钥管理的项目。
常见踩坑与失败案例
- Nginx root 指向项目根目录 —— 结果
composer.json、.env都能被浏览器下载,比默认结构更危险。Web 根必须是web/。 - 插件找不到
wp-content—— 老插件用WP_CONTENT_DIR之外的硬编码。改用 Bedrock 前先排查插件。 - 案例:某团队上了 Bedrock 但没禁用后台更新,同事在后台更新了插件,
composer.lock与实际脱节,下次部署版本回退,站点报错。上 Bedrock 就必须把DISALLOW_FILE_MODS打开。 .env被提交 —— Bedrock 默认已 ignore,但有人图省事git add -f。提交前务必确认。- 升级 WordPress 核心 —— 改
composer.json里的roots/wordpress版本后composer update,不要进后台点更新。
总结
Bedrock 的价值在于把 WordPress 从”装在服务器上的应用”变成”受版本控制的代码项目”。如果你的痛点是多环境不一致、密钥散落、部署靠手工,它非常值得上;如果你只是想让博客跑起来,它的复杂度不划算。判断标准很简单:你有没有”部署流程”这个概念——有的话 Bedrock 加分,没有的话先解决备份和更新规范更实际。
