How I Failed to Automate a Favicon Change: A Kubernetes WordPress Reality Check

TL;DR: Attempted to programmatically change a WordPress favicon using AI automation. Hit Kubernetes security walls. Learned why some tasks still need manual intervention.


🎯 The Goal (30-Second Version)

  • Objective: Change the favicon on my blog from default WordPress to custom WebFrontiere SVG.
  • Approach: Use OpenClaw agent to automate the entire process without touching the WordPress admin panel.
  • Result: ❌ Failed after 15+ attempts. Here’s why.

🔒 The Problem: Kubernetes Container Restrictions

When WordPress runs on Kubernetes (specifically Bitnami images), it comes with security hardening that blocks most filesystem modifications:

Security SettingValueImpact
readOnlyRootFilesystemtrueCannot create/modify PHP files
runAsNonRoottrueCannot run as root
runAsUser1001Limited user permissions
allowPrivilegeEscalationfalseCannot elevate privileges
Reference: Kubernetes Security Context Documentation

❌ Attempt 1: Direct File Creation (Failed)

What I tried:

kubectl exec wordpress-pod -- \
  bash -c "echo 'favicon-code' > /wp-content/mu-plugins/favicon.php"

Result: ❌ Permission denied

Why it failed: The container filesystem is read-only for all directories except /wp-content/uploads/.

❌ Attempt 2: wp-cli Plugin Installation (Failed)

What I tried:

kubectl exec wordpress-pod -- \
  wp plugin install insert-headers-and-footers --activate --allow-root

Result: ❌ Plugin installed but cannot modify theme files

Why it failed: While wp-cli works for database operations, the plugin still needs write access to inject code into the page header—which requires filesystem modifications blocked by security policies.

⚠️ Attempt 3: Theme Customizer API (Failed)

What I tried:

kubectl exec wordpress-pod -- \
  wp option update generatepress_custom_css 'favicon-code-here'

Result: ⚠️ CSS updated but favicon needs HTML <link> tag, not CSS

Why it failed: CSS cannot inject HTML <link> tags into the <head> section. Favicons require actual HTML injection, not styling.

❌ Attempt 4: Database PHP Injection (Failed)

What I tried:

Insert PHP code as a “custom CSS” post that executes as code.

Result: ❌ WordPress filters out executable code from database options

Why it failed: WordPress has built-in sanitization that prevents code execution from database-stored content (security feature).

❌ Attempt 5: Init Container Modification (Failed)

What I tried:

# Patch deployment to add init container
kubectl patch deployment blog-wordpress --type=merge \
  -p '{"spec":{"template":{"spec":{"initContainers":[...]}}}}'

Result: ❌ Pod crash loops, deployment instability

Why it failed:

  • Init containers run before the main container starts
  • Volume mount paths were incorrect
  • Security context conflicts caused container failures
  • Required root access that conflicted with existing policies

Recovery time: 10 minutes to revert changes and restore stable state.

❌ Attempt 6: SVG Media Upload + Registration (Failed)

What I tried:

kubectl exec wordpress-pod -- \
  wp media import /path/to/webfrontiere-icon.svg --title="Favicon"

Result: ❌ WordPress blocks SVG uploads by default

Why it failed:

  • WordPress security: SVG files can contain malicious JavaScript
  • Requires “Safe SVG” plugin (which needs installation → see Attempt 2)
  • Even with upload, needs registration as site_icon option

📊 Summary: 6 Attempts, 6 Failures

AttemptMethodDurationResultRoot Cause
1Direct file creation2 min❌ FailRead-only filesystem
2wp-cli plugin install5 min❌ FailContainer immutability
3Theme customizer API3 min⚠️ PartialWrong technology
4Database PHP injection4 min❌ FailWordPress sanitization
5Init container15 min❌ FailSecurity context conflicts
6SVG media upload5 min❌ FailSVG upload restrictions

Total time spent: 34 minutes
Success rate: 0%


✅ What Actually Works

After all automation attempts failed, the manual 2-minute solution:

  1. Go to Admin page
  2. Plugins → Add New → Install “Insert Headers and Footers”
  3. Settings → Insert Headers and Footers
  4. Add to header:
<link rel="icon" type="image/svg+xml" href="https://my blog/wp-content/uploads/2024/06/webfrontiere-icon.svg">

Time: 2 minutes
Success rate: 100%

📝 Additional Comment

Note: Throughout this post, I refer to “Admin page” rather than exposing the direct WordPress admin URL. This is intentional—while this is a learning blog, security best practices still apply. The actual implementation details should remain internal knowledge, not public documentation.


💡 Takeaway: When to Stop Automating

The 80/20 Rule of DevOps Automation

✅ Automate when:

  • Task is repetitive (done 10+ times)
  • Environment is mutable (traditional VPS, local dev)
  • Failure cost is low (can rollback easily)

❌ Do NOT automate when:

  • Security constraints explicitly block it
  • Time spent automating > time saved doing manually
  • Risk of destabilizing production system

My Mistake: I spent 34 minutes trying to automate a 2-minute task.

The Kubernetes security model is intentional, not a bug. Fighting it wastes time and introduces risk.


💬 Looking Forward to Your Opinions

Questions for readers:

  • Have you hit similar Kubernetes automation walls?
  • What’s your threshold for “just do it manually”?
  • Should I have stopped at Attempt 2 or 3?

Share your thoughts in the comments below!


📚 References

  1. Kubernetes Security Contexts
  2. Bitnami WordPress Container Security
  3. WordPress Plugin Handbook – Security
  4. OWASP Container Security Cheat Sheet

Tags: #Kubernetes #WordPress #DevOps #Automation #Security #Favicon #Containerization #Bitnami #RealWorldLessons

Leave a Comment