[ download_resume.pdf ]
← back to projects
mathew@dfw:~/projects/this-site
guest@portfolio:~$cat this-site/README.md

[OK] This Site started: 2025-05
tech: Astro, nginx, Let's Encrypt, Cloudflare, Node.js, Express, Anthropic API, systemd, Ubuntu 24.04, VPS-native deploy

The Meta-Project

This site is its own project. It runs on an ExtraVM VPS in Dallas, TX — the same box that hosts TrenchWatch. There is no cloud build pipeline, no Vercel, no Netlify. The build happens on the VPS itself, the dist folder gets atomically symlinked into place, and nginx serves it directly.

Stack

Frontend

  • Astro 4.x — static output, TypeScript, content collections backed by Markdown and JSON files
  • Vanilla CSS — amber monochrome palette, scanline overlay, CRT toggle, no framework
  • JetBrains Mono — self-hosted via @fontsource/jetbrains-mono, no Google Fonts

API Backend

  • Node.js / Express — lightweight API server handling Q&A requests against portfolio context
  • Anthropic SDK — streams responses from Claude using the Messages API; the portfolio’s background data is injected as context so answers stay grounded in verified facts
  • Rate limiting — per-IP request throttling on the Express layer to protect against abuse
  • systemd unit (portfolio-api.service) — runs as a persistent service with Restart=on-failure and secrets loaded via EnvironmentFile

Web Server & TLS

  • nginx — SSL termination, reverse proxy to the Node.js API on localhost, security headers: Strict-Transport-Security, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options
  • Let’s Encrypt / certbot — TLS certificates with automatic renewal via systemd timer
  • Cloudflare DNS — authoritative DNS with Full (strict) SSL mode; Cloudflare terminates client TLS, forwards to the VPS over a second verified TLS connection

Server Hardening

  • Ubuntu 24.04 — non-root sudo user for all operations; root login disabled
  • ufw — firewall rules allowing only ports 22, 80, and 443
  • SSH key auth — password authentication disabled in sshd_config

Deploy Workflow

Content changes are a three-step pattern:

# edit a markdown file in src/content/
git add . && git commit -m "update content"
./deploy.sh

deploy.sh runs npm run build, moves the dist to a timestamped release directory, and atomically swaps the symlink at /srv/portfolio/current. Up to five releases are retained for rollback; older ones are pruned automatically. Nginx doesn’t restart — it just starts serving the new files.

Live Status

The VPS status block at the bottom of the home page fetches /status.json every 60 seconds — written by a cron job running every minute on the box itself. If the timestamp is updating, the server is alive.

type help to see available commands
guest@portfolio:~$