Files
homepage/src/index.html
T
2026-05-28 15:44:42 -04:00

587 lines
41 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Reese Wells - Self-Hosting & Infrastructure</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Server Rack Background -->
<div class="server-rack-bg"></div>
<!-- Navigation -->
<nav aria-label="Main navigation">
<div class="nav-inner">
<div class="logo">&lt;Reese /&gt;</div>
<ul class="nav-links" id="navLinks" role="list" aria-label="Primary navigation">
<li><a href="#hero" aria-current="page">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#experience">Experience</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#gpg">GPG</a></li>
</ul>
<button class="hamburger" id="hamburger" aria-label="Toggle menu">
<span></span><span></span><span></span>
</button>
</div>
</nav>
<main>
<!-- Hero -->
<section class="hero" id="hero" aria-label="Introduction">
<div class="hero-content">
<h1>
Hi, I'm <span class="gradient-text">Reese Wells</span><br>
I build and maintain self-hosted systems
</h1>
<p>
A systems-focused developer passionate about self-hosting, infrastructure automation,
and building reliable services that just work. From container orchestration to local AI,
I manage a full homelab stack from DNS to deployment.
</p>
<div class="hero-buttons">
<a href="#projects" class="btn btn-primary">
See My Projects
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M6 3l5 5-5 5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</a>
<a href="#contact" class="btn btn-secondary">Get In Touch</a>
</div>
</div>
</section>
<!-- About -->
<section id="about" aria-label="About">
<div class="about-grid">
<div class="about-image fade-in">
<div class="avatar-frame">
<div class="avatar-inner">
<img src="profile.jpeg" alt="Reese Wells" style="width:100%;height:100%;object-fit:cover;border-radius:22px;">
</div>
</div>
</div>
<div class="about-text fade-in">
<p class="section-label">About Me</p>
<h2 class="section-title">Infrastructure, automation, and self-hosting</h2>
<p>
I'm a systems developer who thrives on building and maintaining self-hosted infrastructure.
My work spans the full stack of homelab operations: from OS image building with osbuild
and Ansible-driven deployments, to container orchestration with Podman quadlets and Kubernetes,
to local AI inference and observability.
</p>
<p>
I maintain two main repositories: one for documentation, notes, and tutorials on
self-hosted services, and another for the automation layer that deploys and manages
services across a fleet of servers. Every service runs as a rootless container with
dedicated systemd user sessions, backed by centralized BorgBackup.
</p>
<div class="about-stats" role="list" aria-label="Key statistics">
<div class="stat" role="listitem">
<div class="stat-number">80+</div>
<div class="stat-label">Services</div>
</div>
<div class="stat" role="listitem">
<div class="stat-number">2</div>
<div class="stat-label">Domains</div>
</div>
<div class="stat" role="listitem">
<div class="stat-number">100%</div>
<div class="stat-label">Self-Hosted</div>
</div>
</div>
</div>
</div>
</section>
<!-- Experience -->
<section id="experience" aria-label="Work Experience">
<p class="section-label fade-in">Experience</p>
<h2 class="section-title fade-in">Where I've worked</h2>
<div class="timeline" role="list" aria-label="Work history">
<div class="timeline-item fade-in" role="listitem">
<div class="timeline-marker"></div>
<div class="timeline-content">
<div class="timeline-header">
<h3>DevOps Manager</h3>
<span class="timeline-company">Nimbis Services</span>
</div>
<span class="timeline-date">Jan 2022 Present</span>
<ul class="timeline-list">
<li>Lead a high-performing DevOps team building microelectronics design services and integrating cloud partner architectures with AWS.</li>
<li>Recruited and led an engineering team to deliver a machine learning platform in &lt;1 year, utilizing Langchain, PyTorch, and BERT to identify government contract patterns.</li>
<li>Reduced new feature QA latency from one week to under 24 hours by containerizing complex infrastructure and developing a custom CLI sandbox.</li>
<li>Led modernization of legacy Django systems using Pydantic, Vue 3, and DRF within strict Authority to Operate boundaries.</li>
<li>Resolved critical SSSD bugs in collaboration with Red Hat and AWS regarding remote authentication protocols via smart cards.</li>
<li>Developed management frameworks that enabled identification of "shadow teams," leading to three successful organizational restructures.</li>
</ul>
</div>
</div>
<div class="timeline-item fade-in" role="listitem">
<div class="timeline-marker"></div>
<div class="timeline-content">
<div class="timeline-header">
<h3>DevSecOps Senior Engineer</h3>
<span class="timeline-company">Nimbis Services</span>
</div>
<span class="timeline-date">Mar 2021 Jan 2022</span>
<ul class="timeline-list">
<li>Engineered a novel version control system using Python for efficient S3 object retrieval, enforcing malware scanning (ClamAV), data signing/chain of custody, and large binary file branching.</li>
<li>Built an integrated SPA interface in Vue 3 with TypeScript/Vuetify to interact with the proprietary version control system.</li>
<li>Utilized Terraform to define and deploy compliant, scalable cloud environments for DoD Impact Level 5+ high-security requirements.</li>
</ul>
</div>
</div>
<div class="timeline-item fade-in" role="listitem">
<div class="timeline-marker"></div>
<div class="timeline-content">
<div class="timeline-header">
<h3>DevOps Engineer</h3>
<span class="timeline-company">Nimbis Services</span>
</div>
<span class="timeline-date">Jan 2020 Jan 2021</span>
<ul class="timeline-list">
<li>Implemented asynchronous malware scanning pipelines using AWS Lambda (containerized) to process and secure files uploaded by engineering teams in real time via ClamAV.</li>
<li>Achieved significant reduction in file management upload overhead through multi-threading, custom indexing solutions, and mtime validation.</li>
</ul>
</div>
</div>
<div class="timeline-item fade-in" role="listitem">
<div class="timeline-marker"></div>
<div class="timeline-content">
<div class="timeline-header">
<h3>Specialist, Information Risk Management</h3>
<span class="timeline-company">Nationwide</span>
</div>
<span class="timeline-date">May 2018 Dec 2020</span>
<ul class="timeline-list">
<li>Developed a web application leveraging BFG Repo-Cleaner to scan/remediate secrets in internal Git repositories; prevented an estimated $500k+ in auditing fines.</li>
<li>Modified "PrivacyScanner" tools to detect and alert on leaked PII data within log aggregators, preventing unauthorized exposure of sensitive user information.</li>
<li>Engineered a Django web platform that automated third-party assessment processes; reduced cycle time from weeks to days through strict field validation.</li>
</ul>
</div>
</div>
</div>
</section>
<!-- Skills -->
<div class="skills-section" id="skills" role="region" aria-label="Skills & Expertise">
<div class="skills-inner">
<p class="section-label fade-in">Skills & Expertise</p>
<h2 class="section-title fade-in">What I work with</h2>
<p class="section-desc fade-in">
A broad toolkit focused on infrastructure, automation, and self-hosted services.
</p>
<div class="skills-grid" role="list" aria-label="Skills">
<div class="skill-card fade-in" role="listitem">
<div class="skill-icon">&#9881;</div>
<h3>Container Orchestration</h3>
<p>Rootless containers managed via Podman quadlets, Docker Compose, and Kubernetes clusters with Helm charts.</p>
<div class="skill-tags">
<span class="skill-tag">Podman</span>
<span class="skill-tag">Docker</span>
<span class="skill-tag">Kubernetes</span>
<span class="skill-tag">k3s</span>
</div>
</div>
<div class="skill-card fade-in" role="listitem">
<div class="skill-icon">&#9883;</div>
<h3>Infrastructure Automation</h3>
<p>Ansible playbooks drive deployments across a multi-server fleet with strict SOP ordering and centralized configuration.</p>
<div class="skill-tags">
<span class="skill-tag">Ansible</span>
<span class="skill-tag">osbuild</span>
<span class="skill-tag">systemd</span>
<span class="skill-tag">BorgBackup</span>
</div>
</div>
<div class="skill-card fade-in" role="listitem">
<div class="skill-icon">&#9729;</div>
<h3>Networking & DNS</h3>
<p>AWS Route53 powers all DNS management with DDNS auto-updating, Caddy reverse proxy with Route53 DNS-validated TLS, and dual-domain strategy.</p>
<div class="skill-tags">
<span class="skill-tag">Route53</span>
<span class="skill-tag">Caddy</span>
<span class="skill-tag">Nginx</span>
<span class="skill-tag">WireGuard</span>
</div>
</div>
<div class="skill-card fade-in" role="listitem">
<div class="skill-icon">&#129302;</div>
<h3>Local AI & ML</h3>
<p>Full local AI stack: Ollama, LiteLLM, LocalAI for inference, Langfuse for observability, with CUDA and ROCm support.</p>
<div class="skill-tags">
<span class="skill-tag">Ollama</span>
<span class="skill-tag">LocalAI</span>
<span class="skill-tag">Langfuse</span>
<span class="skill-tag">ROCm</span>
</div>
</div>
<div class="skill-card fade-in" role="listitem">
<div class="skill-icon">&#10064;</div>
<h3>Python</h3>
<p>Python is the backbone of the homelab: DDNS updates, fleet-wide deployment scripts, AWS integration, and automation tooling with boto3, rich, and uv.</p>
<div class="skill-tags">
<span class="skill-tag">Python</span>
<span class="skill-tag">boto3</span>
<span class="skill-tag">uv</span>
<span class="skill-tag">mypy</span>
</div>
</div>
</div>
</div>
</div>
<!-- Projects -->
<section id="projects" aria-label="Projects">
<p class="section-label fade-in">Featured Projects</p>
<h2 class="section-title fade-in">What I've built</h2>
<p class="section-desc fade-in">
A selection of projects from my homelab and deployment infrastructure.
</p>
<div class="projects-grid" role="list" aria-label="Projects">
<div class="project-card fade-in" role="listitem">
<div class="project-preview">
<div class="code-block">
<div class="code-line"><span class="code-keyword">version</span>: <span class="code-string">'3.8'</span></div>
<div class="code-line"><span class="code-keyword">services</span>:</div>
<div class="code-line">&nbsp;&nbsp;<span class="code-function">caddy</span>:</div>
<div class="code-line">&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-variable">image</span>: <span class="code-string">caddy:2-alpine</span></div>
<div class="code-line">&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-variable">networks</span>:</div>
<div class="code-line">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- <span class="code-string">default</span></div>
<div class="code-line">&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-variable">labels</span>:</div>
<div class="code-line">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- <span class="code-string">"caddy.*.reeseapps.com"</span></div>
</div>
</div>
<div class="project-info">
<h3>Reverse Proxy Infrastructure</h3>
<p>Caddy and Nginx reverse proxies serving all *.reeseapps.com domains with AWS Route53 DNS-validated TLS. DDNS auto-updates IPv4/IPv6 records across the fleet.</p>
<div class="project-meta">
<div class="project-tech">
<span>Caddy</span>
<span>Nginx</span>
<span>Route53</span>
<span>Podman</span>
</div>
<div class="project-links">
<a href="https://gitea.reeseapps.com/services/homelab" title="Source" target="_blank" rel="noopener">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
</a>
</div>
</div>
</div>
</div>
<div class="project-card fade-in" role="listitem">
<div class="project-preview">
<div class="code-block">
<div class="code-line"><span class="code-keyword">def</span> <span class="code-function">update_record</span>(<span class="code-variable">domain</span>):</div>
<div class="code-line">&nbsp;&nbsp;<span class="code-variable">ipv4</span> = <span class="code-function">get_public_ip</span>()</div>
<div class="code-line">&nbsp;&nbsp;<span class="code-variable">record</span> = <span class="code-function">route53</span>.<span class="code-function">find</span>(<span class="code-variable">domain</span>)</div>
<div class="code-line">&nbsp;&nbsp;<span class="code-keyword">if</span> <span class="code-variable">record</span>.<span class="code-variable">value</span> != <span class="code-variable">ipv4</span>:</div>
<div class="code-line">&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-function">route53</span>.<span class="code-function">update</span>(<span class="code-variable">record</span>, <span class="code-variable">ipv4</span>)</div>
<div class="code-line">&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-function">log</span>(<span class="code-string">f"Updated {domain}"</span>)</div>
<div class="code-line">&nbsp;</div>
<div class="code-line"><span class="code-comment"># Run every 5 minutes</span></div>
</div>
</div>
<div class="project-info">
<h3>Dynamic DNS Service</h3>
<p>Automated DDNS keeping AWS Route53 records updated for all servers. Manages dual-domain strategy: reeseapps.com for public services and reeselink.com for internal machine-to-machine connections.</p>
<div class="project-meta">
<div class="project-tech">
<span>Python</span>
<span>AWS CLI</span>
<span>Route53</span>
<span>Podman</span>
</div>
<div class="project-links">
<a href="https://gitea.reeseapps.com/services/homelab" title="Source" target="_blank" rel="noopener">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
</a>
</div>
</div>
</div>
</div>
<div class="project-card fade-in" role="listitem">
<div class="project-preview">
<div class="code-block">
<div class="code-line"><span class="code-keyword">from</span> <span class="code-string">ollama</span> <span class="code-keyword">import</span> <span class="code-function">Client</span></div>
<div class="code-line">&nbsp;</div>
<div class="code-line"><span class="code-variable">client</span> = <span class="code-function">Client</span>(<span class="code-string">"http://localhost:11434"</span>)</div>
<div class="code-line"><span class="code-variable">response</span> = <span class="code-variable">client</span>.<span class="code-function">chat</span>(</div>
<div class="code-line">&nbsp;&nbsp;<span class="code-variable">model</span>=<span class="code-string">"llama3"</span>,</div>
<div class="code-line">&nbsp;&nbsp;<span class="code-variable">messages</span>=[...]</div>
<div class="code-line">)</div>
<div class="code-line">&nbsp;</div>
<div class="code-line"><span class="code-comment"># LiteLLM proxy for unified API</span></div>
</div>
</div>
<div class="project-info">
<h3>Local AI Stack</h3>
<p>Complete local AI infrastructure: Ollama and LocalAI for inference, LiteLLM as a unified API proxy, Bifrost for model routing, and Langfuse for observability. Supports both CUDA and ROCm.</p>
<div class="project-meta">
<div class="project-tech">
<span>Ollama</span>
<span>LocalAI</span>
<span>LiteLLM</span>
<span>Langfuse</span>
</div>
<div class="project-links">
<a href="https://gitea.reeseapps.com/services/homelab" title="Source" target="_blank" rel="noopener">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
</a>
</div>
</div>
</div>
</div>
<div class="project-card fade-in" role="listitem">
<div class="project-preview">
<div class="code-block">
<div class="code-line"><span class="code-comment"># Ansible playbook</span></div>
<div class="code-line"><span class="code-keyword">- name</span>: <span class="code-function">Deploy Gitea</span></div>
<div class="code-line">&nbsp;&nbsp;<span class="code-variable">hosts</span>: <span class="code-string">gitea</span></div>
<div class="code-line">&nbsp;&nbsp;<span class="code-variable">tasks</span>:</div>
<div class="code-line">&nbsp;&nbsp;- <span class="code-function">docker_compose_v2</span>:</div>
<div class="code-line">&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-variable">project_src</span>: <span class="code-string">/opt/gitea</span></div>
<div class="code-line">&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-variable">state</span>: <span class="code-string">present</span></div>
</div>
</div>
<div class="project-info">
<h3>Deployment Automation</h3>
<p>Ansible-driven deployment pipeline with strict SOP ordering (osbuild -> ddns -> caddy -> nginx -> ntfy -> gitea). Each service runs as a rootless container with dedicated systemd user sessions and centralized BorgBackup.</p>
<div class="project-meta">
<div class="project-tech">
<span>Ansible</span>
<span>Podman</span>
<span>systemd</span>
<span>Borg</span>
</div>
<div class="project-links">
<a href="https://gitea.reeseapps.com/services/homelab" title="Source" target="_blank" rel="noopener">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
</a>
</div>
</div>
</div>
</div>
<div class="project-card fade-in" role="listitem">
<div class="project-preview">
<div class="code-block">
<div class="code-line"><span class="code-comment"># Self-hosted services</span></div>
<div class="code-line"><span class="code-keyword">- Immich</span> <span class="code-comment"># Photo/video management</span></div>
<div class="code-line"><span class="code-keyword">- Jellyfin</span> <span class="code-comment"># Media streaming</span></div>
<div class="code-line"><span class="code-keyword">- Nextcloud</span> <span class="code-comment"># Cloud storage & sync</span></div>
<div class="code-line"><span class="code-keyword">- Gitea</span> <span class="code-comment"># Git service</span></div>
<div class="code-line"><span class="code-keyword">- Matrix</span> <span class="code-comment"># Chat protocol</span></div>
<div class="code-line"><span class="code-keyword">- Home Assistant</span> <span class="code-comment"># Smart home</span></div>
<div class="code-line"><span class="code-keyword">- Pi-hole</span> <span class="code-comment"># DNS ad blocking</span></div>
</div>
</div>
<div class="project-info">
<h3>Self-Hosted Services</h3>
<p>A diverse fleet of self-hosted services: Immich for photos, Jellyfin for media, Nextcloud for storage, Matrix for chat, Home Assistant for IoT, and more. Each running as rootless Podman containers with SELinux awareness.</p>
<div class="project-meta">
<div class="project-tech">
<span>Immich</span>
<span>Jellyfin</span>
<span>Nextcloud</span>
<span>Matrix</span>
</div>
<div class="project-links">
<a href="https://gitea.reeseapps.com/services/homelab" title="Source" target="_blank" rel="noopener">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
</a>
</div>
</div>
</div>
</div>
<div class="project-card fade-in" role="listitem">
<div class="project-preview">
<div class="code-block">
<div class="code-line"><span class="code-comment"># Kubernetes with k3s</span></div>
<div class="code-line"><span class="code-keyword">- metallb</span> <span class="code-comment"># L2 load balancer</span></div>
<div class="code-line"><span class="code-keyword">- longhorn</span> <span class="code-comment"># Distributed storage</span></div>
<div class="code-line"><span class="code-keyword">- traefik</span> <span class="code-comment"># Ingress gateway</span></div>
<div class="code-line"><span class="code-keyword">- external-dns</span> <span class="code-comment"># Route53 integration</span></div>
<div class="code-line"><span class="code-keyword">- grafana</span> <span class="code-comment"># Metrics dashboards</span></div>
<div class="code-line"><span class="code-keyword">- minecraft</span> <span class="code-comment"># Game server</span></div>
</div>
</div>
<div class="project-info">
<h3>Kubernetes Cluster</h3>
<p>k3s and k0s Kubernetes clusters with MetalLB for L2 failover, Longhorn for distributed storage, Traefik/Nginx ingress, cert-manager with Route53 DNS challenge, and Helm charts for service deployment.</p>
<div class="project-meta">
<div class="project-tech">
<span>k3s</span>
<span>Kubernetes</span>
<span>Helm</span>
<span>MetalLB</span>
</div>
<div class="project-links">
<a href="https://gitea.reeseapps.com/services/homelab" title="Source" target="_blank" rel="noopener">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Contact -->
<section class="contact-section" id="contact" aria-label="Contact">
<p class="section-label fade-in">Get In Touch</p>
<h2 class="section-title fade-in">Let's connect</h2>
<p class="section-desc fade-in">
Always open to discussing self-hosting, infrastructure, open source, or just sharing homelab stories.
</p>
<div class="contact-links fade-in" role="list" aria-label="Contact links">
<a href="mailto:reese.wells@ducoterra.net" class="contact-link" role="listitem">
<span class="link-icon">&#9993;</span>
<span>Email</span>
</a>
<a href="https://gitea.reeseapps.com/services/homelab" class="contact-link" target="_blank" rel="noopener" role="listitem">
<span class="link-icon">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
</span>
<span>Gitea</span>
</a>
<a href="https://www.linkedin.com/in/reesewells/" class="contact-link" target="_blank" rel="noopener" role="listitem">
<span class="link-icon">in</span>
<span>LinkedIn</span>
</a>
</div>
</section>
<!-- GPG Keys -->
<section class="gpg-section" id="gpg" aria-label="Public GPG Keys">
<p class="section-label fade-in">Trust</p>
<h2 class="section-title fade-in">Public GPG Keys</h2>
<p class="section-desc fade-in" style="margin-left:auto;margin-right:auto;text-align:center;">
Use these keys to verify signed commits and communications. Both keys belong to Reese Wells.
</p>
<div class="gpg-keys-grid" role="list" aria-label="GPG keys">
<div class="gpg-key-card fade-in" role="listitem">
<div class="gpg-key-header">
<span class="gpg-key-icon">&#128274;</span>
<div>
<h3>Primary Key</h3>
<p class="gpg-key-email">reese.wells@ducoterra.net</p>
</div>
</div>
<div class="gpg-key-fingerprint">
<span>Fingerprint:</span>
<code>7FC1 B297 0011 4F4F C589 E706 5FDD CFA5 44D7 7B8C</code>
</div>
<pre class="gpg-key-block"><code>-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEaE5XjhYJKwYBBAHaRw8BAQdAURfgqa4xpT9tTtRETfknsq8UacTcUeXd2P+N
CmdSxw+0IVJlZXNlIFdlbGxzIDxyZWVzZUBkdWNvdGVycmEubmV0PoiPBBMWCAA3
BAsJCAcCFQgCFgECGQECngECmwMWIQR/wbKXABFPT8WJ5wZf3c+lRNd7jAUCaOe5
HQUJBHjscgAKCRBf3c+lRNd7jDo+AP9ElEJP3nsUcW9TbStKwmu0Iq5cjwbDofYx
aoo8lxpgYAEAtEnBYpRz8g94NpCi0TF2EGCmlQupJy1S0nlQdkW3QQq0IVJlZXNl
IFdlbGxzIDxkdWNvdGVycmFAZ21haWwuY29tPoiPBBMWCAA3BAsJCAcCFQgCFgEC
GQACngECmwMWIQR/wbKXABFPT8WJ5wZf3c+lRNd7jAUCaOe5HQUJBHjscgAKCRBf
3c+lRNd7jMoiAP4scAB+6RdRTIo/UvLzI5LdO0Ej1W9i6d09Vmt5T3ES3wD/e2JD
CNwMixU02xbSh0wRFwOmBK1ltw3qoABUIoG4Qgu0H1JlZXNlIFdlbGxzIDxkdWNv
d2FlQGdtYWlsLmNvbT6IjwQTFggANwQLCQgHAhUIAhYBAhkAAp4BApsDFiEEf8Gy
lwART0/FiecGX93PpUTXe4wFAmjnuR0FCQR47HIACgkQX93PpUTXe4w/bgEAgr5K
MJypCb1dmjUmFBBLmvEVT7zt8llZbcsrPqQHZo4BAM2lnEa4pQQ5AZ6XMSlx2dSi
V89/RIugpbqhStR+hGsJtCdSZWVzZSBXZWxscyA8cmVlc2Uud2VsbHNAZHVjb3Rl
cnJhLm5ldD6ImQQTFgoAQRYhBH/BspcAEU9PxYnnBl/dz6VE13uMBQJp36cbAhsD
BQkEeOxyBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEF/dz6VE13uMGwUB
AMZTs+ggIGdyDNNHQKxCjSiFj1tV4txdGMhFs7zg061JAQDsnuEZxZ2r5oM+Hl4e
1JmPiUT7TI3I0KyLzSnrE5TiBbg4BGhOV44SCisGAQQBl1UBBQEBB0DwrTk+obNw
CZVjUW/wi97DI7d1VtebvszT24X04nFSawMBCAeIeAQYFggACQWCaE5XjgKbDAAh
CRBf3c+lRNd7jBYhBH/BspcAEU9PxYnnBl/dz6VE13uM79kA/iGOP6Duiw19F/TT
bIbyO3rh99O5VMtxdgYAxhxLF29gAP9p8UwxP0vhCXrB+VrT3p8ZVNtXYswCsXKY
RZXs6UjJArkCDQRoTleOARAAs92LnhZYtwJvOFFVivXb8ZsgHf6oVdK6/c1htn9K
90hbVbVoArMjrHY+3msoZ0sOBd1s1K3/Q9B0lwDJV6VgEggckIxYc6hpoVu9HmiG
XGdIPzbnnyOeV7NHdYpARPBjXt8HKL96O181qS02WhjIg3sDg3pnuCxJ78nOcNvP
F3ANNpPKr05IWme5NAN+kfKrRaurKP3OePHG6l8ZUWGJPxW+jfE2w1R5hGpEqeu6
RgnfaeBGta10tdJE68+i9RLO1KVDgrIC2c+hNzwMPEMgiiM+MHWgC5uHxpWohv+L
cF4STKLYx8uo9VpwuwNXIh6QEqUm/YWQxcrmrvh4+UNupX00zrzgcUCjJxmyChj8
tyYiM6ltqQ2qOjWLdXZfNbdq0vQw7K1jCMg+kESdFF4jGYGBsYqDBrJXvC0fIJF3
oQIcIc+wGP3kikoj1DREpz53loowMWtSaKx1eZky08PT6KSgM3jefLctfmcpCATL
AKW0FksC9xk6U/UatWwSEZ30ZjOOf2yhnnb1tI0g6EvP3528T4dZiyIWPDwegQZv
Bu2Fa+YcAj5cJ3jLO8UoPtXJA1/3KiIWIXKlchBQtAelvbdikMpJCdl3Yzpx4rJ7
A4Oaz7E0eVKR4ZrU62ti1jM9dMNA5AyTiGxZeBAVXc6CNqZUXyFqLQF7T1zuKWEu
baUAEQEAAYkClwQYFggACQWCaE5XjgKbDgJACRBf3c+lRNd7jMFdoAQZAQgABgUC
aE5XjgAKCRCfMr6uYxJ0la7ED/9/wj2h4ntIynkpU2dLeSuibTRKT4o7EMt2P1wt
7oCvTG4n4CGQy/bRMBqK6nWjRAfyDNyJfXq15lWESEzyvKRHeVjzgBQ3uvmk3485
CYO17aIHfci6NMN2LUD8F5WVsNkP6pxuL/RF4tIfxLWb0hNOVREbxLsFrFcvMpl9
9e3zGEQT8nIo/K25Ex9a3SbPW4zStYvVmg3OI44q85hIMrxyw1OZgzV1aLCYAPGf
Brj941Mm0BEdXO28LulJF5eMqdPSNpzF+VPbkz4A3RcbQ+IC09W8YU3+vRjOshkV
++nrd8GEYzlUWL7osz5JCvtUtvCAEBoGfHcqc328vvurHwvHsACysJ/BPPVPnxs/
NfaFybr9f9wqO/4DA+157kAxNWDyQN3v6bIry0e4H1SijBTosgP/QFVW8Te6A7Xc
k4B+r/buFOi4xZEYcS7Sj1g+xhmHWnr9ogWS9NgVJMxgiaFivB9XqLDD6pRKisfR
ukqAKaHjXtA4HLfLOV95plJoEG9KBWeLGOC2MSrytwplOHZGjyf6eWT3T60fplpW
ZKg97p/WBLy2JsKSBLvAgYOAdSp2lbg+BUEMQR4Ik/yC0MLvrV4+534+Vt+KW1cB
QCW6h0ehT137OR4a79Z94nOA3jdvoI8G5svpsXILXxnnRTaNQBm1bh7706NGszqC
lniyJxYhBH/BspcAEU9PxYnnBl/dz6VE13uMFw4A/0G+/1lmIe06f8wk84ajyrjv
pONgYKHcXyh0UkEKz1ufAQDKmC4MEH0My+HFiCmbgYlaZrL1kCAkhSk6SQ1D0k7S
BQ==
=U3eP
-----END PGP PUBLIC KEY BLOCK-----</code></pre>
</div>
<div class="gpg-key-card fade-in" role="listitem">
<div class="gpg-key-header">
<span class="gpg-key-icon">&#128274;</span>
<div>
<h3>Git Signing Key</h3>
<p class="gpg-key-email">git@ducoterra.net</p>
</div>
</div>
<div class="gpg-key-fingerprint">
<span>Fingerprint:</span>
<code>2FF3 619F A6CA 2A4C FA2D 3532 816E 5FE7 8271 602B</code>
</div>
<pre class="gpg-key-block"><code>-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEaPWJEBYJKwYBBAHaRw8BAQdAkbMCw8vlCTSyvxCnaWvFwvvlm7wW94Fgsj47
3NeMC9a0MVJlZXNlIFdlbGxzIChHaXQgU2lnbmluZyBLZXkpIDxnaXRAZHVjb3Rl
cnJhLm5ldD6ImQQTFgoAQQIbAwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgBYh
BC/zYZ+myipM+i01MoFuX+eCcWArBQJo9l/LBQkDwz27AAoJEIFuX+eCcWArk3cB
AMtkMa5nxG16CaiKMyOGmzlhCZJnS2wvz84DEAMr2BKRAP9Xg//BEVaDMzvRXuU+
Nya5ewmhjfvI0O3dxUfhUIDUCYh1BBAWCgAdFiEEf8GylwART0/FiecGX93PpUTX
e4wFAmj2qewACgkQX93PpUTXe4zbuQD+NiQ8+ubTNSIxoq5qv20rTEIJZwhWamyS
KSCxUnramK0A/Ajzne+dP6ZJh3O96YaTxhQtCibcSqo66/hVndXymvIKiJMEExYK
ADsWIQQv82GfpsoqTPotNTKBbl/ngnFgKwUCaPWJEAIbAwULCQgHAgIiAgYVCgkI
CwIEFgIDAQIeBwIXgAAKCRCBbl/ngnFgK9bsAP47Fth3baT2awbVmlwPEXt17aFI
yIgxXyp9/5DA2QB4QAD/Wy4h8NiWzCzfO6kD1YzgIepVv2UlRH0sQ70vEi5RWAq4
OARo9YkQEgorBgEEAZdVAQUBAQdAeODe7hrNZC143n0+CvNh6x0E9QxGRJfjJPN1
WAV5bWsDAQgHiHgEGBYKACAWIQQv82GfpsoqTPotNTKBbl/ngnFgKwUCaPWJEAIb
DAAKCRCBbl/ngnFgK7kQAQDOnSYe0XO4Hw7QAAo2VhOUHvOjj4c2WSlLuIkyG4n2
XwEAnes79w4eYeMUjIytQWACEvy4QoO7X2MLTKliSqc4Ag8=
=9aAm
-----END PGP PUBLIC KEY BLOCK-----</code></pre>
</div>
</div>
</section>
<!-- Achievements Tracker -->
<section id="achievements" class="achievements-section" hidden aria-label="Achievements">
<div class="section-label">Achievements</div>
<div class="section-title">Terminal Achievements</div>
<p class="section-desc" style="margin: 0 auto 2rem;">Explore every corner of the terminal to unlock achievements.</p>
<div id="achievements-count" style="text-align: center; margin-bottom: 2rem; color: var(--text-muted); font-size: 0.9rem;"></div>
<div id="achievements-grid" class="achievements-grid"></div>
</section>
<!-- Footer -->
</main>
<footer role="contentinfo">
<p style="font-size: 0.75rem; color: var(--text-muted);">
Built with a 100% self-hosted LLM stack running
<a href="https://github.com/ggml-org/llama.cpp" target="_blank" rel="noopener" style="color: var(--accent-hover); text-decoration: none;">llama.cpp</a>,
<a href="https://huggingface.co/Qwen/Qwen3.6-35B-A3B" target="_blank" rel="noopener" style="color: var(--accent-hover); text-decoration: none;">Qwen3.6</a>, and
<a href="https://opencode.ai/" target="_blank" rel="noopener" style="color: var(--accent-hover); text-decoration: none;">Opencode</a>
</p>
</footer>
<script src="script.js" defer></script>
</body>
</html>