Fighting Cloudflare and Fixing Image Pipelines: A Day in the EpsteinScan Trenches
Had one of those debugging days where everything that could go wrong did. Working on the EpsteinScan admin panel, and what started as "just add a Generate Now button" turned into a full infrastructure archaeology expedition.
The Morning Session
Started simple enough. Moved our automated blog generation from 10 AM to 5:30 AM CT because apparently I'm a morning person now. Added a shiny "Generate Now" button to the admin panel that lets me manually trigger content generation instead of waiting for the cron job. The button fires off our blog generator, then our social media post creator, complete with a loading spinner because we're fancy like that.
Generated today's content: "The Physicist's Dilemma: Lawrence Krauss and Epstein's Science Patronage" plus 5 social posts and 3 card images. Not bad for a Tuesday.
When Everything Breaks
Then the fun started. Social card images just... weren't loading. Classic web dev moment.
First culprit: Cloudflare's Bot Fight Mode was throwing 403 errors on ALL our static files. Apparently our server looked suspicious enough to trigger their defenses. One WAF skip rule later, and we're back in business.
Second issue was trickier. The images existed on our dev server (where cron runs the generators) but not on production (where users actually see the site). My solution? Symlinks. Now app/static/social points to app-dev/static/social, so both environments share the same image files. Cron generates on dev, production serves them immediately.
The Architecture Dance
This whole debugging session made me realize our server setup is... interesting. We've got production and dev running side by side, sharing a database via symlink, and now sharing images too. It works, but it's definitely not what you'd find in a textbook.
The current state:
- Production serves the main site
- Dev runs all the automated content generation
- They share a database and now image directories
- Only dev has git deployment (production is still file-copy based)
Small Wins
Fixed the "Generate Now" button visibility issue - it was hiding inside the wrong template block. Also restored the missing TikTok nav link that got lost somewhere along the way.
Set up proper git deployment for the dev environment. Now it's just git pull origin dev && supervisorctl restart instead of manually copying files around like it's 2005.
What's Next
Still need to fix a small bug in the social media generator where it chokes on SQLite row objects. And I should probably get production on git-based deployment too before the template drift gets worse.
But hey, the admin panel works, images are loading, and content is generating. Sometimes that's enough for one day.
The messy reality of build-in-public: not every day is shipping features. Sometimes you're just making sure the lights stay on.