The short version
This site is a Laravel 13 app running as two containers, nginx and PHP-FPM, under Docker Compose. It runs on the VM that hosts my dylanbanta.com projects, behind the nginx reverse-proxy VM that fronts my whole homelab, with Cloudflare in front of that.
The container layout comes from my own dockerized-laravel-template, the same one behind every site in the dlt case study.
What it deliberately doesn't have
The template normally adds a database, user accounts and an admin panel. I took all of that out. This site has:
- No database. All the content is Markdown and JSON files, versioned in git.
- No login and no admin panel. Nobody needs to sign in to a portfolio.
- No Livewire or other interactive server components.
Everything a site runs is something I have to keep patched, so I left out whatever a portfolio doesn't need. What's left is a small set of PHP, a few templates and some JavaScript for the timeline.
Content and design
Every page is a Markdown file with a short header block. A few special blocks turn into components: the flow diagrams, callouts and stat rows you see on the case studies. The projects grid and the timeline are JSON. Editing the site means editing text files and committing them.
The styling follows my Theme Contract, the design-token system I wrote for my Laravel sites. Colors, radii, shadows and fonts are all CSS custom properties, so the site has one bespoke theme with light and dark variants, and no component hardcodes a color.
How it's updated
- Content changes are edits to Markdown or JSON files. The app reads them directly, so there's no build step and no restart.
- Design or script changes need a Vite build for the CSS and JavaScript. Those files are fingerprinted, so browsers never mix old and new versions.
- Proxy changes are checked with
nginx -tbefore nginx reloads, so a typo can't take the edge down.
Built with AI assistance
I built this site with Claude Code: the app, the templates and the first drafts of the writing. I directed it, reviewed and edited what it produced, and made the decisions. I use AI tools the way I'd want a colleague to: openly, and taking responsibility for the result.