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 Setting | Value | Impact |
|---|---|---|
readOnlyRootFilesystem | true | Cannot create/modify PHP files |
runAsNonRoot | true | Cannot run as root |
runAsUser | 1001 | Limited user permissions |
allowPrivilegeEscalation | false | Cannot elevate privileges |
❌ 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
| Attempt | Method | Duration | Result | Root Cause |
|---|---|---|---|---|
| 1 | Direct file creation | 2 min | ❌ Fail | Read-only filesystem |
| 2 | wp-cli plugin install | 5 min | ❌ Fail | Container immutability |
| 3 | Theme customizer API | 3 min | ⚠️ Partial | Wrong technology |
| 4 | Database PHP injection | 4 min | ❌ Fail | WordPress sanitization |
| 5 | Init container | 15 min | ❌ Fail | Security context conflicts |
| 6 | SVG media upload | 5 min | ❌ Fail | SVG upload restrictions |
Total time spent: 34 minutes
Success rate: 0%
✅ What Actually Works
After all automation attempts failed, the manual 2-minute solution:
- Go to Admin page
- Plugins → Add New → Install “Insert Headers and Footers”
- Settings → Insert Headers and Footers
- 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
- Kubernetes Security Contexts
- Bitnami WordPress Container Security
- WordPress Plugin Handbook – Security
- OWASP Container Security Cheat Sheet
Tags: #Kubernetes #WordPress #DevOps #Automation #Security #Favicon #Containerization #Bitnami #RealWorldLessons