Real and Works logo Real and Works
Case study

The Self-Hosted Course Business

Selling knowledge online usually means renting three businesses from three vendors: a
storefront, a learning platform, and — increasingly — an AI that reads your own course material back to
you off someone else’s server, metered by the token. I went the other way on the two that matter. The
shopfront out front can be anyone’s WordPress; the parts that are the business — the courseware
and the tutor — run on hardware I own. I run three of my own companies on this exact platform, in three
unrelated markets, off one design.

The split is deliberate. A WooCommerce storefront is a commodity: it takes the money and it can live
on any host, because nothing irreplaceable lives there. The Moodle LMS — every course,
every cohort’s questions, every forum thread — and the tutor model that answers
students are the assets, so they sit on my own machines. When a student asks the tutor a question, the
question and the curriculum never leave the building. That is the whole point, and it is worth being
precise about how it’s wired.

One purchase, fully automated, end to end

The platform turns a sale into an enrolled, supported student with no human in the loop. A paid
WooCommerce order fires a signed webhook into an n8n workflow, which verifies the
signature, maps the purchased SKUs to Moodle courses, creates the student account if it’s new, and
enrols them — then Moodle emails their credentials. From “card approved” to “logged into the right
course” is a few seconds, and it’s gateway-agnostic: it fires on payment, so it works whether
the buyer tapped a card through PayFast or iKhokha — or paid in crypto through NOWPayments.

  rented shopfront                onboard — hardware I own
  ┌────────────────────┐          ┌────────────────────┐    ┌────────────────────┐
  │ WordPress +        │ paid     │ Moodle LMS (sg1)   │    │ Tutor agent (inky) │
  │ WooCommerce        │ order    │ courses · forums   │◄──►│ Qwenopus on a 3090 │
  │ (any external host)│─────────►│ Web Services API   │    │ ↕ Obsidian vault   │
  └────────────────────┘ signed   └────────────────────┘    └────────────────────┘
            │             webhook            ▲
            └─ n8n: verify HMAC · map SKU→course · create + enrol student ─┘
The till is rented; the classroom and the teacher run on my hardware.

The emitter that sends the webhook is idempotent — it stamps each order so a retry or a status
flip can’t double-enrol anyone, and there’s a one-click “resend enrolment” action on the order for the
rare case a downstream call fails. The webhook acknowledges in under a second and lets the Moodle calls
run after the response, because a large multi-course order can mean a dozen-plus API round trips; making
the shop wait on all of them is how you get false “failed” states on enrolments that actually succeeded.
Small decision, but it’s the difference between a pipeline you trust and one you babysit.

The tutor that curates its own knowledge base

The piece I’m proudest of isn’t the plumbing — it’s the forum tutor, and it runs entirely on my own
GPU. Students ask questions in the course forums the way they always have. A resident agent, backed by a
self-hosted model (Qwenopus 3.6 via llama.cpp on a 3090), watches those
threads and answers from a curated Obsidian vault that holds the course’s real
knowledge. Because the model is mine and the vault is mine, a student question and the answer that course
material implies never become a third party’s training data or a line on a metered bill.

But it does more than answer. Every resolved question is written back into the vault as a reusable
question-and-answer note, so the knowledge base grows from the actual confusion of real cohorts.
And when a new student asks something that’s already been answered — phrased differently, as it always
is — the agent recognises it as the same question rather than writing a duplicate, and instead increments
a count of how many students have hit it.

That counter is quietly the most valuable output of the whole system. “Forty-one students asked this,
in thirty-one different ways” is not a support ticket — it’s a heat-map of exactly where a course is
unclear. The forum stops being a cost centre and becomes the course’s editing instructions. Support that
normally scales with enrolment instead scales with the number of distinct things students don’t
yet understand — and that number shrinks every time I fix the material it points at.

To be exact about what this is and isn’t: it is not vector RAG. There’s no embedding store doing
fuzzy similarity search over the whole curriculum. It’s curated retrieval from a hand-tended knowledge
base plus semantic clustering of questions — and for tightly-scoped courseware, where every
answer should trace to something a human deliberately wrote, that’s more reliable and more auditable than
letting an embedding index improvise. I’d rather a tutor that says exactly what the course says than one
that’s confidently adjacent to it.

Three businesses, one platform

The strongest proof that this is a product and not a one-off is that it’s running, unchanged in shape,
behind three businesses in completely different markets:

  • AfrEcoSoil sells biological soil-rehabilitation knowledge — the Bio 1 course,
    the soil-assessment flow, the farmer programmes — to growers.
  • PtyLaunchpad sells South African company-formation and compliance courses — register,
    run and protect a (Pty) Ltd under the Companies Act — to founders, across a whole catalogue of
    sector-specific tracks that the SKU-to-course mapping enrols automatically.
  • HermesForge sells an AI-agent training program to a third audience again — the
    storefront on hermesagentforge.com, the courseware delivered on a self-hosted Moodle, and
    checkout taking card via iKhokha or crypto via NOWPayments. Same machine, new vertical.

Soil farmers, company founders and agent-builders have nothing in common, which is the entire point. The verticals are
swappable; the machine underneath — store, signed enrolment pipeline, onboard LMS, self-hosting tutor — is
the same. Standing up the next one is a deployment, not a rebuild.

What it costs versus what it buys

I won’t pretend the self-hosted half is free. Running your own Moodle means you own the upgrades, the
backups, and the 11pm “why is the LMS slow” page; running the tutor on your own card means you own driver
skew and the power bill whether or not a student is online tonight. There’s no managed-LMS SLA to hide
behind. You’re trading a tidy stack of monthly invoices for being the ops team — owning the Moodle
upgrades is real enough work that I built and open-sourced a tool to de-risk it,
Upgrade H5P Medic.

What you get back is the part that compounds. Tutoring costs collapse from a per-token meter to a power
draw, so the agent can answer every student every time without anyone doing arithmetic about the bill.
The curriculum — the actual asset — never leaves hardware I control, so it can’t be trained on, leaked, or
priced out from under me. And the knowledge base is worth more after every cohort than before it, because
the questions students ask are folded back into the material. For a business whose product is
knowledge, owning where that knowledge lives isn’t a nice-to-have. It’s the moat.

Live on the platform

Both of these are real businesses taking real enrolments right now: