Initial portfolio site: Astro + Tailwind MVP

Outcome-led hero, about, grouped skills, experience summary, featured
projects + /projects index, static contact, SEO/OG, dark/light theme.
Dockerfile + nginx config + build script for homelab deploy.
This commit is contained in:
2026-06-17 16:22:53 +10:00
commit 2d4b6ea097
38 changed files with 8232 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
// Short experience summary for the About section (M1).
// A fuller, dated timeline lands in M2.
// TODO(Jonathon): fill employer names, exact titles, and dates.
export type Role = {
title: string;
org: string;
period: string;
summary: string;
highlights: string[];
};
export const experience: Role[] = [
{
title: "Platform / Infrastructure Engineer",
org: "TODO: Employer", // TODO(Jonathon)
period: "TODO: dates", // TODO(Jonathon)
summary:
"Operate and automate a fleet of GPU-backed edge Kubernetes clusters running computer-vision workloads, plus the IaC pipelines that deploy them.",
highlights: [
"Hardened GPU readiness and egress networking across the edge fleet",
"Built Ansible/AWX automation for repeatable cluster bring-up",
"Owned observability and network policy for the platform",
],
},
{
title: "TODO: Previous role",
org: "TODO: Employer", // TODO(Jonathon)
period: "TODO: dates", // TODO(Jonathon)
summary: "TODO(Jonathon): one or two lines on a previous role.",
highlights: [],
},
];
+82
View File
@@ -0,0 +1,82 @@
// Featured project cards for the homepage + the basic /projects index (M1).
// In M2 these become full case-study Content Collections at src/content/projects/.
// Keep `slug` stable so the M2 migration keeps the same URLs.
export type Project = {
slug: string;
title: string;
// One-line "so what" outcome — the most important field.
outcome: string;
summary: string;
role: string;
period: string;
stack: string[];
featured: boolean;
// Set true in M2 when /projects/[slug] case studies exist.
hasCaseStudy?: boolean;
};
export const projects: Project[] = [
{
slug: "edge-gpu-inference-platform",
title: "Edge Kubernetes / GPU Inference Platform",
outcome:
"Made GPU computer-vision reliable across a fleet of store-edge clusters — no more inference pods racing the GPU at boot.",
summary:
"A fleet of single-purpose edge Kubernetes clusters running GPU-accelerated computer-vision workloads. Hardened the GPU readiness path (init-gated so pods never schedule before the device plugin is up) and corrected the egress NAT path so inference results reached upstream services reliably.",
role: "Platform / Infrastructure Engineer",
period: "Recent", // TODO(Jonathon): dates
stack: ["OpenShift", "NVIDIA GPU Operator", "Multus", "SNAT / egress", "GPU device plugin"],
featured: true,
},
{
slug: "cv-compliance-verifier",
title: "Computer-Vision Compliance Verifier",
outcome:
"Turned a manual visual check into a containerized GPU workload emitting a structured pass/fail verdict.",
summary:
"A YOLO-based vision tool packaged as a containerized workload on GPU edge nodes. Runs an inference pipeline against a defined scene and emits a structured, machine-readable verdict — replacing a manual, subjective check with a repeatable one.",
role: "Platform / Infrastructure Engineer",
period: "Recent", // TODO(Jonathon): dates
stack: ["YOLO", "Containers", "GPU nodes", "Kubernetes", "Structured output"],
featured: true,
},
{
slug: "self-hosted-agent-infra",
title: "Self-Hosted AI Agent Infrastructure",
outcome:
"Ran a private, channel-connected AI agent on my own hardware — no third-party platform holding the data or the keys.",
summary:
"A self-hosted agent on a GPU workstation with a Signal-based sibling agent, built on a skill/context-loading framework. Local LLM inference, scoped tool access, and a credential model where the agent never holds a downstream secret directly.",
role: "Builder",
period: "Ongoing",
stack: ["Local LLM (llama.cpp)", "Agent framework", "Skills/tooling", "Signal channel", "RTX 5080"],
featured: true,
},
{
slug: "homelab-platform",
title: "Homelab Platform",
outcome:
"A production-grade homelab: GitOps from bare metal to apps, with the same rigor I'd apply at work.",
summary:
"Proxmox with PCIe passthrough (GPU/SATA) underneath single-node Talos clusters, all driven by ArgoCD GitOps. Split-horizon DNS, SSO, observability, NAS-backed restic backups, and local LLM inference on a Blackwell GPU — the platform that hosts this very site.",
role: "Owner / Operator",
period: "Ongoing",
stack: ["Proxmox", "Talos", "ArgoCD", "Cilium", "Cloudflare Tunnel", "Prometheus"],
featured: false,
},
{
slug: "iac-fleet-automation",
title: "IaC Automation for Fleet Deployments",
outcome:
"Stood up identical edge clusters from code — GPU stack, networking, and secrets templated, not hand-configured.",
summary:
"Ansible/AWX playbooks for fleet deployment: GPU operator install, CNI and templated network attachments, container image pre-pull, and secrets delivered via Vault — so a new edge site comes up the same way every time.",
role: "Automation Engineer",
period: "Recent", // TODO(Jonathon): dates
stack: ["Ansible", "AWX", "Vault", "Multus", "GPU Operator"],
featured: false,
},
];
export const featuredProjects = projects.filter((p) => p.featured);
+34
View File
@@ -0,0 +1,34 @@
// Central site config — single source of truth for identity + metadata.
// Edit here, not in components.
export const site = {
name: "Jonathon Wright",
// Short handle used in the mono "logo".
handle: "jwright",
role: "Infrastructure Engineer",
// Outcome-led positioning (hero headline).
positioning:
"Building secure Kubernetes platforms, automated infrastructure fleets and GPU-backed edge systems.",
// Supporting capability line under the headline.
tagline: [
"Talos Linux",
"Kubernetes",
"GitOps",
"Ansible",
"Observability",
"Edge AI",
],
// One-paragraph elevator pitch for the About section.
bio: "I design and run platforms that have to keep working when no one is watching — fleets of GPU-backed Kubernetes clusters at the edge, the IaC pipelines that deploy them, and the observability and network policy that keep them honest. I care about reliability you can reason about, security that's the default rather than a bolt-on, and automation that removes the manual step entirely instead of documenting it.",
// Canonical URL (used for OG/sitemap/RSS).
url: "https://www.bztmon.com",
// Contact.
email: "jonny.wright225@gmail.com",
// Set when a real CV is dropped at public/cv.pdf — the button is hidden until then.
// Detection is automatic (see Layout/Hero); this is just an override if ever needed.
ogImage: "/og.png",
locale: "en",
} as const;
export type Site = typeof site;
+86
View File
@@ -0,0 +1,86 @@
// Grouped capability matrix — NO percentage bars / ratings / logo walls.
// Driven entirely by this file; the Skills section renders whatever is here.
export type SkillGroup = {
title: string;
// Short framing line for the group.
blurb: string;
items: string[];
};
export const skills: SkillGroup[] = [
{
title: "Platform Engineering",
blurb: "Kubernetes platforms designed to be reasoned about and recovered.",
items: [
"Kubernetes",
"Talos Linux",
"OpenShift",
"ArgoCD / GitOps",
"Helm & Kustomize",
"Cilium / flannel",
"Gateway API & Ingress",
],
},
{
title: "Infrastructure Automation",
blurb: "Removing the manual step entirely, not documenting it.",
items: [
"Ansible",
"AWX",
"GitOps pipelines",
"Renovate",
"Image pre-pull & templating",
"Reproducible cluster bring-up",
],
},
{
title: "Linux & Systems",
blurb: "From the hypervisor up to the workload.",
items: [
"Debian / RHEL",
"systemd",
"Proxmox / KVM",
"PCIe / GPU passthrough",
"LVM & block storage",
"restic / SMB backup",
"Bash & PowerShell",
],
},
{
title: "Networking & Security",
blurb: "Default-deny, least-privilege, and a small attack surface.",
items: [
"Split-horizon DNS",
"Cloudflare Tunnel",
"Reverse proxy (Traefik / nginx)",
"NetworkPolicies",
"OIDC / SSO (Authentik)",
"Secrets (Vault / Infisical / ESO)",
"TLS & cert-manager",
],
},
{
title: "Observability",
blurb: "Knowing the system is healthy, not just the pods.",
items: [
"Prometheus",
"Grafana",
"Alertmanager",
"node-exporter / kube-state-metrics",
"ServiceMonitors",
],
},
{
title: "AI & GPU Infrastructure",
blurb: "Serving vision and language models on real hardware.",
items: [
"NVIDIA GPU Operator",
"Multus / SR-IOV",
"YOLO / computer-vision inference",
"Local LLM serving (llama.cpp)",
"Agent frameworks & tooling",
"Hardware-isolated workloads (Kata)",
],
},
];
+31
View File
@@ -0,0 +1,31 @@
// Social / contact links. `mailto` is built from site.email.
// TODO(Jonathon): confirm GitHub + LinkedIn handles (placeholders below).
export type Social = {
label: string;
href: string;
// Inline SVG path data (24x24 viewBox) so we ship zero icon-font / external requests.
icon: string;
// External link gets rel=noopener; mailto does not.
external?: boolean;
};
export const socials: Social[] = [
{
label: "GitHub",
href: "https://github.com/jwrong96", // TODO(Jonathon): confirm public GitHub handle
external: true,
icon: "M12 .5A11.5 11.5 0 0 0 .5 12a11.5 11.5 0 0 0 7.86 10.92c.58.1.79-.25.79-.56v-2c-3.2.7-3.88-1.37-3.88-1.37-.53-1.34-1.3-1.7-1.3-1.7-1.06-.72.08-.71.08-.71 1.17.08 1.78 1.2 1.78 1.2 1.04 1.79 2.73 1.27 3.4.97.1-.76.41-1.27.74-1.56-2.55-.29-5.24-1.28-5.24-5.7 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.18 1.18a11 11 0 0 1 5.8 0c2.2-1.5 3.17-1.18 3.17-1.18.63 1.59.24 2.76.12 3.05.74.81 1.18 1.84 1.18 3.1 0 4.43-2.69 5.4-5.25 5.69.42.36.8 1.08.8 2.18v3.23c0 .31.21.67.8.56A11.5 11.5 0 0 0 23.5 12 11.5 11.5 0 0 0 12 .5Z",
},
{
label: "LinkedIn",
href: "https://www.linkedin.com/in/jonathon-wright", // TODO(Jonathon): confirm LinkedIn URL
external: true,
icon: "M20.45 20.45h-3.56v-5.57c0-1.33-.02-3.04-1.85-3.04-1.85 0-2.14 1.45-2.14 2.94v5.67H9.35V9h3.41v1.56h.05c.48-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28ZM5.34 7.43a2.07 2.07 0 1 1 0-4.14 2.07 2.07 0 0 1 0 4.14ZM7.12 20.45H3.55V9h3.57v11.45ZM22.22 0H1.77C.8 0 0 .78 0 1.74v20.51C0 23.22.8 24 1.77 24h20.45c.98 0 1.78-.78 1.78-1.75V1.74C24 .78 23.2 0 22.22 0Z",
},
{
label: "Email",
href: "mailto:jonny.wright225@gmail.com",
icon: "M2 4h20c.55 0 1 .45 1 1v14c0 .55-.45 1-1 1H2c-.55 0-1-.45-1-1V5c0-.55.45-1 1-1Zm1.4 2 8.6 6 8.6-6H3.4ZM21 7.87l-8.43 5.9a1 1 0 0 1-1.14 0L3 7.87V18h18V7.87Z",
},
];