From 1b31cb574e7d3926e53211b0cae5d184806fcc2e Mon Sep 17 00:00:00 2001 From: herbygitea Date: Tue, 31 Mar 2026 02:00:52 +0000 Subject: [PATCH] Create cloudflare-cache-rules.md via n8n --- PBS/Tech/Sessions/cloudflare-cache-rules.md | 86 +++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 PBS/Tech/Sessions/cloudflare-cache-rules.md diff --git a/PBS/Tech/Sessions/cloudflare-cache-rules.md b/PBS/Tech/Sessions/cloudflare-cache-rules.md new file mode 100644 index 0000000..752201d --- /dev/null +++ b/PBS/Tech/Sessions/cloudflare-cache-rules.md @@ -0,0 +1,86 @@ +--- +project: cloudflare-cache-rules +type: session-notes +status: active +tags: + - pbs + - cloudflare + - caching + - production + - wordpress +created: 2026-03-30 +updated: 2026-03-30 +path: PBS/Tech/Sessions/ +--- + +# Cloudflare Cache Rules - Fix & Cleanup - March 30, 2026 + +## Problem + +After production server migration (clone → update → promote), Cloudflare cache broke admin functionality. Jenny's post edits were reverting on save — the editor was serving stale cached versions of wp-admin pages. Both the IP-based bypass rule and the wp-admin path bypass rule were failing. + +## Root Causes Found + +### 1. Cloudflare Cache Rules use "last match wins" +Unlike Page Rules (first match wins), Cache Rules are **stackable** — all matching rules apply, and for conflicting settings, the **last matching rule wins**. Our bypass rules were ordered above the Cache Everything rule, so Cache Everything was always winning. + +### 2. Missing leading slashes on URI paths +The wp-admin bypass rule had `wp-admin` instead of `/wp-admin`, so it never matched actual request paths like `/wp-admin/post.php`. + +### 3. Invalid n8n/Gitea entries in path rules +Full URLs (`https://n8n.plantbasedsoutherner.com`) were in URI Path filters, which only match path portions (like `/wp-admin/`). These entries were doing nothing. n8n and Gitea already have Cloudflare proxy disabled, so cache rules aren't needed for them. + +### 4. Staging URL contamination +473 references to `staging.plantbasedsoutherner.com` were baked into the WordPress database from the server migration — post content, Elementor data, postmeta, GUIDs, and plugin caches. + +## What We Fixed + +### Cache Rule Reordering +Moved Cache Everything to position **1** (top) with bypass rules below it. Since last match wins, the bypass rules now correctly override caching. + +**Current rule order:** +1. Cache Everything (2hr Edge TTL, 1 day Browser TTL, serve stale while revalidating) +2. Bypass Cache - PBS Admins (cookie: `pbs_admin_bypass`) +3. Bypass Cache - WP Admin Paths (`/wp-admin`, `/wp-login.php`) +4. Bypass Cache - WooCommerce (`/cart`, `/checkout`, `/my-account`, `woocommerce` cookie) + +### URI Path Fixes +- Added leading slashes: `/wp-admin`, `/wp-login.php`, `/cart`, `/checkout`, `/my-account` +- Removed invalid full-URL entries for n8n and Gitea + +### Cookie-Based Admin Bypass +- Replaced IP-based bypass with custom `pbs_admin_bypass` cookie +- Confirmed working via Cloudflare Trace and DevTools (`CF-Cache-Status: DYNAMIC`) +- Cookie set manually in DevTools for now — WPCode snippet for auto-set on admin login is next + +### Staging URL Cleanup +- Ran WP-CLI search-replace inside Docker container: + ``` + docker exec -it wordpress wp search-replace 'staging.plantbasedsoutherner.com' 'plantbasedsoutherner.com' --all-tables --allow-root + ``` +- 473 replacements made across wp_posts, wp_postmeta, and GUIDs +- Flushed Redis object cache: `wp cache flush --allow-root` +- Manually cleared stale plugin caches: Jetpack site icon, Astra partials cache +- Deleted `astra_partials_config_cache` from wp_options to force regeneration + +### Debugging Tools Used +- Cloudflare **Trace** (Rules → Trace): Simulates a request and shows which rules match in order — confirmed both bypass and Cache Everything were firing, with Cache Everything winning +- Browser DevTools Network tab: Checked `CF-Cache-Status` response header +- `curl` blocked by Cloudflare bot challenge (Bot Fight Mode) — use DevTools instead + +## Key Learnings + +- **Cloudflare Cache Rules: last match wins** — opposite of Page Rules. Put broad rules first, specific overrides below. +- **URI Path filters only match paths** — never full URLs with hostnames +- **Always include leading slashes** in URI path filters (`/wp-admin` not `wp-admin`) +- **Server cloning contaminates URLs** — always run `wp search-replace` after migrating/cloning WordPress between environments +- **WP-CLI handles serialized data safely** — never do raw SQL find-and-replace on WordPress content (Elementor data can break) +- **`wp-config.php` tip**: Add `define('FS_METHOD', 'direct');` to suppress FTP credentials prompt in Docker + +## Still To Do + +- [ ] WPCode Lite snippet to auto-set `pbs_admin_bypass` cookie on admin login +- [ ] Clean up Rule 2 extra expressions (leftover `tjherbranson` wildcard and `starts_with` conditions) +- [ ] Create scoped Cloudflare API token (Zone.Cache Purge only) +- [ ] Build n8n auto-purge workflow (WordPress publish/update → Cloudflare targeted cache purge) +- [ ] Decide: auto-purge homepage on content updates? \ No newline at end of file