Engineering notes from the trenches of building software.
Practical, no-hype writing for developers and businesses - on AI, ERPNext, Frappe, Linux and shipping software. I cut through the noise to what actually works, with a sharp eye on what it all means for Africa.
- 471
- Articles
- 33
- Topics
- 11
- Years writing
Featured article
Don't Get Pressured Into Buying AI Before Your Business Is Ready
The hype says buy AI now or be left behind. The truth is most businesses aren't ready yet, and rushing wastes money, frustrates teams and quietly breaks customer trust. Using the Ngazi ladder, here's how to find the rung you're really on and take the one step that pays off.
Recent articles
Deploying Frappe apps to a client server you're not allowed to touch
The client will not give you access to their dev server, so every code change means someone on their side pulls and migrates by hand. Here is the complete fix: a self-hosted runner they install, a deploy script they own, and no credential to their environment on your side at all.
The pull model: systemd timers and release polling
When the client's security team refuses a runner outright, you can still ship. A systemd timer on their server asks GitHub what the latest release is, compares it against what is checked out, and deploys when they differ. Nothing external can execute anything.
Push access is code execution: hardening a self-hosted runner
A self-hosted runner executes whatever the workflow file says, and the workflow file lives in a repository you control. So push access to your repository is command execution on your client's server. Here is the honest risk and the layers that contain it.
SSH deployment for Frappe: how it works, and what it costs you
SSH deployment is the right answer when you own the server, and here is a complete working pipeline for it. It is also a private key held by a third party's CI system, which is a bill worth reading before you sign it.
What bench migrate actually does, and the rollback you'll wish you had
Every patch commits as it completes and records itself as applied. So a migration that fails halfway is not a failed migration, it is a half-finished one, and re-running will not undo it. Here is the recovery, with real commands.
Anatomy of a Frappe bench
Five directories, one of which is not a directory at all but a collection of independent git repositories. Understanding that is the difference between a deploy that works and a Saturday spent fixing file ownership.