Back to portfolio

Case Study: Jason Holt Photography (Next.js + Azure)

Built a professional photography portfolio + booking website as a real client-acquisition tool, then containerized and deployed it on Azure (ACR + Container Apps) with repeatable CI/CD.

Last updated: January 2026

Summary

What I built

  • Gallery browsing and presentation optimized for photography content.
  • Booking workflow via TidyCal integration.
  • Contact form protected with Cloudflare Turnstile and third-party form handling.
  • SEO + performance-focused implementation (metadata, image optimization workflow).

Tech stack

  • Framework: Next.js (App Router) + TypeScript
  • UI: Tailwind CSS + shadcn/ui
  • Deployment: Docker image → Azure Container Registry → Azure Container Apps
  • CI/CD: GitHub Actions

Azure deployment (high level)

The deployment is container-first: build a production image, push to ACR, and deploy to a Container App with external ingress.

  • Built for linux/amd64 (important when building on Apple Silicon).
  • Used a managed identity approach for secure image pulls (AcrPull) rather than relying only on admin creds.
  • Environment variables managed via GitHub Secrets/Variables and injected at deploy time.

AI-assisted iteration (“vibe coding”)

I used Cline + Sonnet 3.7 to move fast on scaffolding and iteration, then validated the results with real constraints: production deployment, SEO, performance, and security basics (forms, tokens, secrets).

The point of this section is not “AI hype” — it’s demonstrating a repeatable process for using AI tools while still shipping responsibly.

Key learnings

  • Containerizing a Next.js app forces clarity around build steps, runtime env vars, and reproducibility.
  • Architecture mismatches (Apple Silicon → linux/amd64) are easy to miss until deploy time.
  • Production polish lives in the details: forms, bot protection, image workflows, and SEO metadata.