Why a Second Site
dmt-lab.nl had grown into a focused ITAM/SAM portfolio — 14 blog articles, a 10-section single-page layout, a working Mon/Thu LinkedIn auto-publisher behind it. The site does its job. But the AI work I'd been doing in parallel — local LLM stack, Claude Code as primary IDE, the n8n auto-publisher build itself, the algorithmic trading platform — didn't fit there. Adding more sections would dilute the ITAM positioning. Mixing AI articles into the existing blog would muddy the analytics signal that Mon/Thu cadence is calibrated for.
The right answer was a second site. Same Bee Hive design system. Same deployment topology (Contabo + Nginx Proxy Manager + Cloudflare DNS). Separate content track. Separate contact pipeline. Separate Docker container.
The constraint I gave myself: do it in one Claude Code session, end-to-end, including scaffold, content rewrite, and deploy. If AI-assisted development is really how I work now, that's the test.
The Setup
Existing infrastructure I could lean on:
- DNS for
ai.dmt-lab.nlalready pointed to the Contabo server's A record (161.97.132.42). - The shared Docker network
nginx-reverse-proxy_defaultis how Nginx Proxy Manager reaches application containers — already wired into the dmt-lab.nl compose file. - Resend was already configured for the parent domain
dmt-lab.nl, so a sender likeai.dmt-lab.nl <contact@dmt-lab.nl>works without verifying a second domain. - Host port 3001 was taken by the existing site; 3002 was free.
That left the actual work as: code scaffold, content rewrite, container build, NPM proxy host, smoke test.
Scaffolding Strategy
Three options, in increasing engineering effort:
- Copy-and-prune the existing codebase, strip the sections that don't apply, rewrite content in place.
- Fresh Next.js init, then lift only the components needed.
- Monorepo with shared package — restructure both sites into apps/* + packages/ui.
Option 3 is the cleanest long-term but doubles the work scope (you have to migrate the production site too). Option 2 is purist but means re-establishing every layout decision from scratch. Option 1 ships fastest, accepts that the two codebases will drift, and treats them as siblings rather than children of a shared base.
I picked option 1. The honest tradeoff: I'll have to apply theme tweaks twice. The honest reward: the new site went from empty directory to deploy-ready in hours, not days.
What Got Pruned
Out of the 11 sections on dmt-lab.nl, four don't make sense on an AI-only site:
- Publications — the itSMF article is ITAM-specific.
- Recommendations — LinkedIn testimonials are about the ITAM/SAM track, not AI work.
- Pricing — kept on dmt-lab.nl where consulting inquiries originate.
- Spare Time — the AI subset of spare-time projects (HomeLab AI rig, n8n publisher, algorithmic trading) became regular Projects on this site, not side projects.
That left seven nav items: Home, About, Journey, Projects, Skills, Blog, Contact.
Content Rewrites
The constants file (src/lib/constants.ts) is the source of truth for all section content on this codebase. Every section component reads from there, so rewriting one file rewrote the whole site:
- New
TYPING_STRINGS,HERO_CONTENT,ABOUT_CONTENT. - New
TIMELINE_DATA— six AI-relevant entries instead of nine ITAM-career ones. - New
PROJECTS_DATA— six AI projects (AI-1 to AI-6) with the same Problem/Approach/Outcome shape as before, but new platform tags: Applied AI, Built with AI, Local AI Lab. - New
COMPETENCY_DOMAINS— four skill clusters: LLM Engineering, AI-Assisted Development, AI Workflow Automation, and Foundations (the cluster that explicitly anchors to the ITAM heritage).
Two design choices I made deliberately:
Keep one career-foundation entry. A site about AI doesn't need to hide the 20 years that came before. The journey ends with a single compressed entry — "2004–2024 — 20 years in IT & ITAM — The Foundation" — pointing at dmt-lab.nl for the full track. That gives credibility without distracting from the AI focus.
The fourth skills cluster is "Foundations". Python, SQL, Docker, REST APIs, data pipelines — these aren't new skills, they're the bedrock that makes AI work in enterprise. Naming them explicitly is more honest than pretending the AI work appeared out of nowhere.
Contact-Form Differentiation
The simplest distinguishing pattern that doesn't require new infrastructure: same Resend account, same recipient inbox, but a different subject prefix and a different from display name.
await resend.emails.send({
from: "ai.dmt-lab.nl <contact@dmt-lab.nl>",
to: process.env.CONTACT_EMAIL,
replyTo: email,
subject: `[ai.dmt-lab.nl] Contact from ${name}`,
text: `Source: ai.dmt-lab.nl\nName: ${name}\n...`,
});
A Gmail filter on the subject prefix is enough to keep AI inquiries separate from ITAM ones without forwarding addresses, mailbox aliases, or new sender domains to verify in Resend.
Deploy Topology
The new container slots into the existing infrastructure exactly the same way as dmt-lab.nl:
services:
web:
build: .
ports:
- "3002:3000"
restart: unless-stopped
environment:
- NODE_ENV=production
- RESEND_API_KEY=${RESEND_API_KEY}
- CONTACT_EMAIL=${CONTACT_EMAIL}
networks:
- default
- npm-network
networks:
npm-network:
external: true
name: nginx-reverse-proxy_default
Two important details:
- Host port 3002. dmt-lab.nl uses 3001. Each site gets its own host port and its own container; they share the npm-network so NPM can route between them.
- The npm-network is
external: true. That's how an app container joins NPM's existing network without needing to manage the network from the app's compose file.
Then Nginx Proxy Manager gets a new Proxy Host: ai.dmt-lab.nl → <container-name>:3000 (the in-container port, not the host port), with a Let's Encrypt SSL certificate.
What Took the Longest
Not the code. The content rewrites — the journey paragraphs, the project descriptions, the about-section arc. Getting the AI-builder-on-an-ITAM-foundation tone right without sounding either dismissive of the past or apologetic about the AI focus. That was the work.
Claude Code is excellent at the mechanical part: scaffold, file edits, type matching, route rewiring. The judgment calls — what to keep, what to cut, what voice to use — are still where the human work happens. The acceleration is real, but it's not in writing more sentences. It's in not having to context-switch between coding and writing every five minutes.
What This Means For Future Companion Sites
Now that the clone-and-prune pattern is documented and validated, future companion sites — a niche AI topic, a specialized consulting track, anything that doesn't fit one of the two existing portfolios — can be spun up in hours rather than days. The pattern is:
rsyncthe existing codebase, excludingnode_modules,.next,.git,.env,tsbuildinfo.- Prune sections that don't apply to the new topic.
- Rewrite
src/lib/constants.tsend-to-end. - Update metadata (
layout.tsx,sitemap.ts,robots.ts,opengraph-image.tsx,feed.xml/route.ts,blog/[slug]/*). - Update Resend sender display name and subject prefix.
- Add a new compose file with a fresh host port; deploy.
- Add an NPM proxy host with Let's Encrypt SSL.
Seven steps, none of them surprising. The whole thing fits in one session.
That's the value of AI-assisted development for this kind of work: it doesn't make the impossible possible. It makes the merely tedious fast enough that you actually do it, instead of letting the idea sit on a backlog for a year.