I Gave Up Too Early. The Problem Was One Line.
Fixing the thing I settled for three months ago
- I couldn't figure it out, so I installed Google Analytics like a person who has given up
- The actual problem was a Caddy config directive. It took one afternoon to find
- Three months of the wrong tool because I stopped looking too soon
I built a blog to write about infrastructure. Then I put Google Analytics on it.
I know.
The original plan was Tinybird — privacy-respecting, Ghost-native, no data handed to Google. I set up the workspace, deployed the schemas, wired up the environment variables. Something wasn't working. I couldn't immediately see what. I had posts to publish.
So I reached for the familiar thing and told myself I'd fix it later.
Later was three months.
The setup wasn't broken. I just stopped looking.
A forgotten password brought me back to the server.
Ghost 6 had shipped while I wasn't paying attention. My install was Ghost 5 on MariaDB — a combination the new version wouldn't touch. Getting back in required a database migration first. MariaDB to MySQL 8. Ghost 5 to 6. Then I was back at the analytics problem I'd abandoned.
I enabled the Tinybird toggle. Every page hit returned a 404.
I checked the environment variables. Checked the tokens. Read the container logs. Everything looked correct, which is the most annoying possible diagnostic result.
The actual problem was in the Caddyfile.
I was routing /.ghost/analytics/* to the traffic-analytics container, but Caddy was forwarding the full path. The container expected requests at /api/v1/page_hit. It was receiving /.ghost/analytics/api/v1/page_hit. That prefix mismatch was the entire problem.
handle_path instead of reverse_proxy. One directive. Three months of Google Analytics.
Forty-five rows in Tinybird inside of five minutes.
What I actually did wrong
I didn't defer this. I abandoned it with a placeholder that removed all pressure to return.
Once Google Analytics was in, the site had analytics. The problem felt solved. It wasn't. I had just made the wrong state comfortable enough to live with.
That's the failure mode worth naming. Not the Caddy config. The decision to make the broken thing livable instead of finding out why it was broken.
A system that's wrong but functional is harder to fix than one that's visibly broken. You have to choose to care, and there's nothing forcing you to.
The Bigger Pattern
Temporary solutions that remove urgency are the most expensive decisions in any sequence.
Not because they cost money. Because they kill the signal.
I've watched this happen in every environment I've worked in. The workaround gets documented. The ticket gets closed. The wrong thing becomes load-bearing. Six months later nobody remembers why it's there and everyone's afraid to touch it.
On a personal blog the stakes are low. The pattern is the same.
Where I Landed
Google Analytics is gone. Tinybird is working. Ghost 6 is running on MySQL 8.
Email is still broken — DigitalOcean blocks outbound SMTP at the network level by default and I have a support ticket open. That one I can't fix myself. Everything else is done.
The site is what I meant to build in December.
Closing Thought
At the end of the session, the Tinybird dashboard showed one visitor. Sixteen page views. That visitor was me.
Three months of the wrong tool because I stopped looking after the first attempt didn't work.
The config was always fixable. I just needed to stay in the room long enough to find out where the problem actually was.