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.

~1,885
businesses indexed
~40%
marketing email open rate
Daily
automated discovery
CMS → Azure
rebuilt & migrated

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

Scraper
Node.js · Azure Container Instance
Discovery providers
SerpAPI · Google Places · Overpass
Dedup + lead scoring
non-destructive merge
CSV export
45-column → Blob
discovered businesses → deduped → scored → CSV

Data

PostgreSQL
Azure Flexible Server · ~28 tables
Azure Blob Storage
business images · scraped leads
read / written by the API

.NET 10 API · Clean Architecture

15 minimal-API modules
business · search · portal · jobs · admin
CQRS + MediatR
validation pipeline · Result pattern
Background workers
bulk email · job-notification dispatcher
Auth
Clerk · business JWT · API keys
JSON over HTTPS

Next.js 14 frontend

Public directory
search · browse · claim
Business portal
profile · payments · jobs
Admin console
moderation · bulk email

External services

Stripe
tiered payments
Clerk
portal auth
Resend
transactional + bulk email
Turnstile
anti-bot
Sentry
errors + tracing
PostHog
analytics

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.

Get in touchBack to projects