Velkommen til min blog!

En personlig blog er endelig en realitet. Her er historien om hvordan sitet blev til, hvilken tech-stack der er brugt — og hvad der venter.

Jeg har i årevis tænkt på at starte en personlig blog. Ikke for at blive "influencer" eller bygge et publikum — men fordi jeg synes det er sundt at skrive tingene ned. At tænke højt. At have et sted der er mit eget.

Det sted er nu her.

Hvad er dette site?

jakob-rohde.com er to ting i én:

En offentlig blog — det du læser nu — hvor jeg skriver om teknologi, projekter og hvad der ellers optager mig. Ingen betalingsmur, ingen nyhedsbrev, ingen tracking.

En privat sektion til familien. Et sted vi kan dele billeder, økonomi og andre ting der ikke hører hjemme på det offentlige internet. Adgang kræver login og to-faktor godkendelse.

Tech-stacken

Jeg har bevidst valgt teknologi jeg kan styre selv — ingen managed services, ingen vendor lock-in.

Framework: Next.js 16 med App Router og TypeScript overalt. Server Components og Server Actions giver en arkitektur der er enkel at ræsonnere over: data hentes på serveren, kun det nødvendige sendes til browseren.

Styling: Tailwind CSS + shadcn/ui. Shadcn er ikke et komponentbibliotek man installerer — det er kode man ejer. Det betyder ingen afhængighed af en tredjeparts release-cyklus.

Autentificering: better-auth med TOTP to-faktor. Jeg rullede min egen auth i stedet for at bruge en managed løsning som Clerk eller Auth0. Det var mere arbejde, men jeg ved præcis hvad der sker med mine brugeres data: det ligger i en SQLite-fil på min egen server.

Database: SQLite via better-sqlite3 og Drizzle ORM. SQLite er undervurderet til projekter i denne størrelse. Én fil, ingen server, ingen netværksforsinkelse. Drizzle giver type-sikkerhed helt ned til databasen.

Deployment: Ubuntu Server 26.04 på en Proxmox-VM hjemme hos mig. PM2 holder Next.js kørende og genstarter det ved nedbrud eller genstart. Nginx Proxy Manager håndterer SSL og routing. Cloudflare sidder foran og absorberer trafikken.

Processen

Sitet startede faktisk som noget andet. Den første version kørte på Vercel med Supabase som database og autentificering — den hurtige, managed vej.

Det fungerede fint, men det passede ikke med hvad jeg egentlig ville: fuld kontrol, intet der kørte hos andre. Så jeg migrerede. Alt. Supabase Auth blev til better-auth, Postgres blev til SQLite, Vercel blev til en VM i min stue.

Det var ikke uden bump på vejen. Et par eksempler:

Kysely-konflikten. better-auth bundler sine egne afhængigheder, herunder en udgave af kysely der mangler nogle konstanter i sit primære export. Next.js 16 med Turbopack validerer disse imports statisk og fejler buildet. Løsningen: et lille postinstall-script der patcher den indlejrede fil og tilføjer de manglende re-exports.

__Secure- cookie-præfikset. better-auth tilføjer automatisk __Secure- foran cookie-navne når sitet serveres over HTTPS. Vores Edge-proxy tjekkede kun for jakob.session_token — og fandt selvfølgelig aldrig __Secure-jakob.session_token. Resultatet: login lykkedes, men brugeren blev ved med at blive sendt tilbage til login-siden.

QR-koden der forsvandt. Under opsætning af to-faktor sætter better-auth twoFactorEnabled = true med det samme når man kalder enable()inden brugeren har scannet QR-koden og bekræftet koden. Det fik React til at opdage at 2FA var aktiveret og navigere væk. Et useEffect der respekterer det aktive enrollment-flow løste det.

Ingen af disse fejl stod i dokumentationen. Det er den slags man opdager ved at gøre det.

Hvad kommer der?

Jeg har ikke en redaktionel plan. Jeg skriver om det der optager mig: software, infrastruktur, hjemmeprojekter. Indimellem måske noget der slet ikke handler om teknologi.

Det her indlæg er start nok.

Kommentarer (0)

Ingen kommentarer endnu. Vær den første!

Log ind for at kommentere.