Skip to content
← All projects
2026Design, build, infrastructure

This site — a self-hosted portfolio with a real pipeline

An animation-forward portfolio that treats itself as a production system: staging and production environments, automatic TLS, CI that lints, typechecks and builds every push, advisory Lighthouse budgets, and a rate-limited server route behind the live egress-proxy demo.

Next.jsTypeScriptGSAPCoolifyCI/CD
≈ £0extra hosting — a new Coolify project on a server that was already paid for

Architecture

  1. 1Author — Next.js App Router, TypeScript, typed content in two files
  2. 2Animate — GSAP and Motion, reduced-motion aware
  3. 3Verify — lint, typecheck, build on every push; Lighthouse advisory
  4. 4Build — once, in CI: standalone output, smoke-tested over real HTTP, promoted to a deploy branch
  5. 5Ship — Coolify copies that tree into a runtime-only image: develop to staging, main to production

The problem

A portfolio is a production system with one user who matters and no second chance at a first impression. It should demonstrate front-end craft, performance discipline and real deployment practice — not just list them.

Approach & decisions

  • Content is visible before JavaScript runs, and every animation is gated behind prefers-reduced-motion. prefers-reduced-transparency turns the glass surfaces solid. Nothing on the page depends on an animation firing.
  • The live demo on the egress-proxy case study calls the deployed proxy from a server-side route, not from the browser — no CORS exposure, a per-IP rate limit, an input cap, and the upstream address kept in configuration rather than the client bundle.
  • Staging is noindexed by header and robots rule, so the test site is never the one a recruiter finds by accident.
  • Build once, promote the artifact. The first on-host build stalled the shared server under memory pressure; rather than buy a bigger box, the pipeline was reshaped so the bytes CI verified are the bytes that ship, and a deploy can never compete with production for memory.
  • The interactive WebGL portrait reveal lives on a branch, deliberately unshipped until its calibration is finished. A working, accessible hero beats an impressive one that never leaves the branch.

Results

  • Two environments, one push each — develop deploys to staging, main to production — with automatic Let's Encrypt TLS.
  • The serving host never compiles. next build peaks at about 1.5 GB, more than a shared 8 GB box has spare, so CI builds once and promotes the verified tree; the host's only job is a COPY.
  • Zero additional hosting cost: it reuses an existing Hetzner server.
  • Honours prefers-reduced-motion, prefers-reduced-transparency and forced-colors from one stylesheet, with every piece of content visible before JavaScript runs.

Stack

Next.jsTypeScriptTailwind CSSGSAPMotionDockerCoolifyGitHub Actions