fix(wordpress): give the site the permalink structure /wp-json needs

WordPress registers /wp-json as a rewrite rule, so it exists only while the
permalink structure is non-empty. A fresh install ships an empty one and
nothing here ever set it: the role flushed rewrite rules it had never asked
for. Every request to /wp-json therefore matched no rule, left the query vars
empty, and WordPress answered the front page with HTTP 200.

Measured in run 34687966607, both compose+tor WordPress#0 jobs. The captured
response to an anonymous POST /wp-json/mcp/mcp-adapter-default-server is the
blog front page, not a JSON-RPC reply, and the page advertises its own REST
root as index.php?rest_route=/ - the form WordPress emits only for an empty
structure. Nothing in roles/, cli/ or scripts/ sets permalink_structure.

That 200 was read as two different accusations, both false.
test-mcp-guest.js took it for "the adapter answered an anonymous probe" and
registerMcpDisabledState would take it for "the surface is still listening
after the flag went false". 604843bb8 acted on the first one and hardened
rest_pre_dispatch, which the request never reaches; that guard only starts
working now.

The rewrite plumbing is already in place: openresty proxies without rewrite or
try_files (sys-svc-proxy/templates/location/html.conf.j2), so Apache is what
routed a path with no file behind it into index.php, which needs mod_rewrite
and .htaccess. No consumer depends on the plain form either - ?rest_route=
appears nowhere in the repository while six files use /wp-json.

The read follows the idiom 06_update_domain.yml already uses twice for home
and siteurl, failed_when: false included, and the write is an option update
rather than a rewrite structure --hard because the flush that file performs
runs right after through the include. Neither task can abort a deploy that
would otherwise have succeeded.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-09-12 16:20:14 +02:00
1 parent 4ce588fea1
commit 197d74416d
2 files changed
+16

No files matched your search

@@ -44,6 +44,21 @@
plugin_task_path: "{{ [role_path, 'tasks/addons', plugin_name ~ '.yml' ] | path_join }}"
when: plugin_enabled | bool
- name: "⬇️ Get current 'permalink_structure'"
shell: >
container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }}
wp option get permalink_structure --path={{ WORDPRESS_DOCKER_HTML_PATH }}
register: wp_permalink_structure
changed_when: false
failed_when: false
- name: "🔗 Set the permalink structure the /wp-json routes need"
shell: >
container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }}
wp option update permalink_structure "{{ WORDPRESS_PERMALINK_STRUCTURE }}"
--path={{ WORDPRESS_DOCKER_HTML_PATH }}
when: (wp_permalink_structure.stdout | trim) != WORDPRESS_PERMALINK_STRUCTURE
- name: 🔍 Detect if WordPress is Multisite
shell: >
container exec -u {{ WORDPRESS_USER }} {{ WORDPRESS_CONTAINER_ADDRESS }}
+1
View File
@@ -38,6 +38,7 @@ WORDPRESS_CONFIG_UPLD_REL: "config/upload.ini"
WORDPRESS_CONFIG_UPLD_ABS: "{{ [lookup('container', application_id, 'directories.instance'), WORDPRESS_CONFIG_UPLD_REL ] | path_join }}"
WORDPRESS_MU_PLUGINS_DIR: "{{ [WORDPRESS_DOCKER_HTML_PATH, 'wp-content/mu-plugins'] | path_join }}"
WORDPRESS_PERMALINK_STRUCTURE: "/%postname%/"
WORDPRESS_ADMIN_EMAIL: "{{ lookup('config', application_id, 'users.administrator.email') }}"
WORDPRESS_ADMIN_USER: "{{ lookup('config', application_id, 'users.administrator.username') }}"