4.4 KiB
| project | type | status | tags | created | updated | path | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| cloudflare-cache-rules | session-notes | active |
|
2026-03-30 | 2026-03-30 | 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:
- Cache Everything (2hr Edge TTL, 1 day Browser TTL, serve stale while revalidating)
- Bypass Cache - PBS Admins (cookie:
pbs_admin_bypass) - Bypass Cache - WP Admin Paths (
/wp-admin,/wp-login.php) - Bypass Cache - WooCommerce (
/cart,/checkout,/my-account,woocommercecookie)
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_bypasscookie - 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_cachefrom 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-Statusresponse header curlblocked 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-adminnotwp-admin) - Server cloning contaminates URLs — always run
wp search-replaceafter 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.phptip: Adddefine('FS_METHOD', 'direct');to suppress FTP credentials prompt in Docker
Still To Do
- WPCode Lite snippet to auto-set
pbs_admin_bypasscookie on admin login - Clean up Rule 2 extra expressions (leftover
tjherbransonwildcard andstarts_withconditions) - 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?