703 lines
46 KiB
HTML
703 lines
46 KiB
HTML
<!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="icon" type="image/png" href="favicon.png">
|
||
<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"><Reese /></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 <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">⚙</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">⚛</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">☁</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">🤖</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">❐</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"> <span class="code-function">caddy</span>:</div>
|
||
<div class="code-line"> <span class="code-variable">image</span>:
|
||
<span class="code-string">caddy:2-alpine</span></div>
|
||
<div class="code-line"> <span class="code-variable">networks</span>:
|
||
</div>
|
||
<div class="code-line"> - <span
|
||
class="code-string">default</span></div>
|
||
<div class="code-line"> <span class="code-variable">labels</span>:
|
||
</div>
|
||
<div class="code-line"> - <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"> <span class="code-variable">ipv4</span> = <span
|
||
class="code-function">get_public_ip</span>()</div>
|
||
<div class="code-line"> <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"> <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"> <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"> <span class="code-function">log</span>(<span
|
||
class="code-string">f"Updated {domain}"</span>)</div>
|
||
<div class="code-line"> </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"> </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"> <span class="code-variable">model</span>=<span
|
||
class="code-string">"llama3"</span>,</div>
|
||
<div class="code-line"> <span class="code-variable">messages</span>=[...]</div>
|
||
<div class="code-line">)</div>
|
||
<div class="code-line"> </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"> <span class="code-variable">hosts</span>: <span
|
||
class="code-string">gitea</span></div>
|
||
<div class="code-line"> <span class="code-variable">tasks</span>:</div>
|
||
<div class="code-line"> - <span class="code-function">docker_compose_v2</span>:
|
||
</div>
|
||
<div class="code-line"> <span
|
||
class="code-variable">project_src</span>: <span
|
||
class="code-string">/opt/gitea</span></div>
|
||
<div class="code-line"> <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">✉</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">🔒</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">🔒</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="terminal.js" defer></script>
|
||
<script src="script.js" defer></script>
|
||
</body>
|
||
|
||
</html> |