Case study · Darras Index
From shared hosting to a platform I own end to end.
Darras Index is a UK local-services directory I co-own and run as Head of IT. I took it from a site hosted on Ionos to a containerised, automated platform on Microsoft Azure — owning architecture, migration, automation, vendors and the backlog along the way.
01 — Overview
What Darras Index is
Darras Index is a genuinely localcommunity directory — every business on it is local to the area. It's a searchable index of roughly 1,885 businesses across 12 categories, with reviews, a job board, and a self-service portal where owners claim and manage their listing.
The model is simple: populate the directory automatically, then earn revenue by charging businesses for premium listings. Discovery and outreach are automated so the directory grows on its own and owners are invited in.
02 — The journey
Ionos → Azure
The site began as a proof-of-concept built on a CMS and hosted on shared hosting. The vision — a fully custom local directory — was something the CMS simply couldn't deliver, so in mid-2025 I came on board to rebuild it properly.
The hosting situation made the move urgent. We hit real instability — outages, a deleted repository, and email deliverability problems: because campaigns were sending from an IP shared with other tenants, our marketing was landing in spam. We parted ways with the original provider, and by November 2025 I had rebuilt the product and migrated everything onto a custom, containerised stack on Azure that we fully control.
That experience is exactly why the platform is now architected for ownership and resilience: our own infrastructure, our own repositories and CI/CD, our own sending reputation — nothing critical sitting in someone else's shared pool.
03 — Architecture
How it's built
Three deployable services on Azure. A .NET 10 API (Clean Architecture, CQRS with MediatR) sits at the centre, backed by PostgreSQL and Blob Storage. A Next.js front-end serves the public directory, the owner portal and the admin console. A Node.js scraper runs nightly to discover and enrich new businesses.
Data ingestion · nightly
Data
.NET 10 API · Clean Architecture
Next.js 14 frontend
External services
Hosting & DevOps
- Azure App Service (Linux containers)
- Azure Container Registry
- Azure Container Instances (scraper)
- Azure DevOps CI/CD
- Docker (multi-stage)
- Deploy-slot swaps
04 — Automation & growth
Filling the directory, automatically
Rather than enter businesses by hand, a scheduled pipeline does it. Every day a containerised scraper runs a fresh location-based search, discovers businesses from several data sources, enriches each record from multiple data points, and deduplicates non-destructively across providers. It then calls our API to insert the business, fire the outreach email, and add the lead to our CRM — directory populated, owner invited, all in one run.
Owners receive a one-time, signed link (sent via Resend) to claim their listing; claiming bridges a Clerk login to a business-scoped JWT so they can manage their profile and upgrade. On top of that, growth runs through Resend marketing emails — hitting up to a ~40% open rate — and social campaigns built around short-form video.
Bulk-email and tiered job-notification jobs run as background workers inside the API, so outreach and notifications scale without manual effort.
05 — Engineering
Decisions that keep it maintainable
Clean Architecture + CQRS
Domain → Application → Infrastructure → API, with MediatR handlers and a validation pipeline. Use cases are isolated and testable.
Result pattern, not exceptions
Handlers return Result<T, ProblemDetails>; exceptions stay genuinely exceptional and map to RFC 7807 responses.
Auto-discovered API modules
15 minimal-API modules wired up by reflection — new features add a module, not controller plumbing.
Multi-scheme auth
Clerk for owners, signed business JWTs for portal calls, API keys for internal writes — enforced per route.
Provider-agnostic scraper
An IDiscoveryProvider interface means new data sources slot in without touching dedup, scoring or export.
Zero-downtime deploys
Docker images to ACR, deployed to Azure App Service via deploy-slot swaps; EF migrations apply on startup.
06 — My role
Every element of IT
I'm the sole engineer and a co-owner. That means I've owned every element of IT here: dealing with providers, planning and executing the migration, designing the architecture, making the infrastructure and build-vs-buy calls, and organising and prioritising the backlog so the most valuable work ships first.
A constant theme is cost discipline — deliberately reaching for free and low-cost tools while we grow, and automating anything repetitive so a one-person tech team can run a platform that discovers businesses, onboards owners and markets itself with very little manual overhead.
07 — Outcomes
Results
Migrated off shared hosting
Rebuilt the CMS proof-of-concept as a fully custom, containerised platform on Azure — owned infrastructure, repositories and sending reputation.
A self-growing directory
~1,885 local businesses indexed, discovered and onboarded by a daily automated pipeline rather than manual data entry.
Marketing that lands
Resend email campaigns reaching up to a ~40% open rate, plus short-form video social campaigns — a step change from deliverability landing in spam.
Run lean by one engineer
Automation and a deliberate free-tools-first approach keep costs down and let a solo tech function operate the whole platform.
Want the full story?
Happy to walk through any part of this — the migration, the architecture, or the automation that keeps it running.