Refine portfolio design and screenshot layouts

This commit is contained in:
Keith Casko
2026-06-20 22:45:38 -04:00
parent 6bfa37f727
commit 596c8add21
2 changed files with 743 additions and 513 deletions
+190 -174
View File
@@ -3,218 +3,234 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ByteGeist Cloud</title> <meta name="description" content="ByteGeist is Keith Casko's self-hosted infrastructure lab and engineering case study." />
<title>ByteGeist — Self-hosted infrastructure</title>
<link rel="icon" href="assets/images/bytegeist-logo.png" />
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>
<header class="site-header"> <header class="site-header">
<a class="brand" href="#"> <a class="brand" href="#top" aria-label="ByteGeist home">
<img src="assets/images/bytegeist-logo.png" alt="ByteGeist logo" /> <img src="assets/images/bytegeist-logo.png" alt="" />
<span>ByteGeist</span> <span>ByteGeist</span>
</a> </a>
<nav> <nav aria-label="Primary navigation">
<a href="#architecture">Architecture</a> <a href="#architecture">Architecture</a>
<a href="#operations">Operations</a> <a href="#systems">Systems</a>
<a href="#security">Security</a> <a href="#lessons">Lessons</a>
<a href="#development">Development</a>
<a href="#platform">Platform</a>
<a href="#recovery">Recovery</a>
</nav> </nav>
<a class="nav-button" href="https://wiki.casko.dev">Docs</a> <a class="text-link header-link" href="https://wiki.casko.dev">Read the docs <span>↗</span></a>
</header> </header>
<main> <main id="top">
<section class="hero"> <section class="hero">
<div class="hero-copy"> <div class="hero-copy">
<p class="eyebrow">Self-Hosted Infrastructure Platform</p> <p class="kicker"><span></span> Home lab / ongoing project</p>
<h1>Infrastructure, security, monitoring, and automation <span>built from scratch.</span></h1> <h1>A production-minded cloud, running on my own hardware.</h1>
<p> <p class="hero-intro">
ByteGeist Cloud is a self-hosted infrastructure platform built on Ubuntu, Docker, ByteGeist is where I test infrastructure decisions for real: identity, observability,
Authentik, Grafana, Loki, Prometheus, CrowdSec, Gitea, and Woodpecker CI. deployments, security, and recovery. It currently runs 26 Docker containers on Ubuntu.
</p> </p>
<div class="actions"> <div class="actions">
<a href="#architecture" class="button primary">Explore Architecture</a> <a href="#architecture" class="button primary">See how it works</a>
<a href="https://git.casko.dev" class="button secondary">View Git Server</a> <a href="https://git.casko.dev" class="text-link">Browse the Git server <span>↗</span></a>
</div> </div>
</div> </div>
<div class="hero-art"> <figure class="hero-visual">
<img src="assets/images/bytegeist-logo.png" alt="ByteGeist cyber ghost logo" /> <img src="assets/images/portfolio-grafana-operations.png" alt="ByteGeist operations dashboard in Grafana" />
</div> <figcaption>
<span>Live operations view</span>
Grafana / Prometheus / cAdvisor
</figcaption>
</figure>
</section> </section>
<section class="stats"> <section class="project-facts" aria-label="Project facts">
<div><strong>26</strong><span>Containers</span></div> <div><span>01</span><strong>26 containers</strong><small>deployed with Compose</small></div>
<div><strong>20+</strong><span>Services</span></div> <div><span>02</span><strong>Central identity</strong><small>SSO and 2FA via Authentik</small></div>
<div><strong>11</strong><span>Protected Apps</span></div> <div><span>03</span><strong>Full observability</strong><small>metrics, logs, and uptime</small></div>
<div><strong>SSO</strong><span>Authentik</span></div> <div><span>04</span><strong>Documented recovery</strong><small>tested restore procedures</small></div>
<div><strong>CI/CD</strong><span>Woodpecker</span></div>
</section> </section>
<section id="architecture" class="split-section"> <section id="architecture" class="architecture section-rule">
<div class="panel large"> <div class="section-heading">
<p class="eyebrow">Architecture Overview</p> <p class="section-index">01 / Architecture</p>
<h2>Designed like a small production platform.</h2>
<p>
Traffic flows through Nginx Proxy Manager, access is controlled through Authentik,
and the environment is monitored, logged, secured, backed up, and documented.
</p>
<img src="assets/images/bytegeist-architecture.png" alt="ByteGeist architecture diagram" />
</div>
<div class="panel about">
<p class="eyebrow">About ByteGeist</p>
<h2>Built to prove real infrastructure skills.</h2>
<ul>
<li>Centralized SSO and 2FA</li>
<li>Monitoring and log aggregation</li>
<li>Automated CI/CD pipelines</li>
<li>Threat detection and response</li>
<li>Backups and disaster recovery</li>
<li>Technical documentation</li>
</ul>
</div>
</section>
<section id="operations" class="section">
<p class="eyebrow">Operations</p>
<h2>Monitoring & Logging</h2>
<div class="card-grid two">
<article class="card">
<img src="assets/images/portfolio-grafana-operations.png" alt="Grafana operations dashboard" />
<h3>Infrastructure Monitoring</h3>
<p>Grafana dashboards show uptime, CPU, memory, disk, container metrics, and system health.</p>
</article>
<article class="card">
<img src="assets/images/portfolio-grafana-logs.png" alt="Grafana logs dashboard" />
<h3>Centralized Logging</h3>
<p>Loki and Grafana provide searchable logs for containers and infrastructure troubleshooting.</p>
</article>
</div>
</section>
<section id="security" class="section">
<p class="eyebrow">Security</p>
<h2>Identity & Threat Protection</h2>
<div class="card-grid two">
<article class="card">
<img src="assets/images/portfolio-authentik-applications.png" alt="Authentik application portal" />
<h3>Centralized Identity</h3>
<p>Authentik provides SSO, OAuth2, OIDC, Forward Auth, access control, and 2FA.</p>
</article>
<article class="card">
<img src="assets/images/portfolio-crowdsec-decisions.png" alt="CrowdSec decisions list" />
<h3>Threat Detection & Response</h3>
<p>CrowdSec detects malicious SSH activity and creates firewall decisions to block attackers.</p>
</article>
</div>
</section>
<section id="development" class="section">
<p class="eyebrow">Development</p>
<h2>Git Hosting & CI/CD</h2>
<div class="card-grid two">
<article class="card">
<img src="assets/images/portfolio-gitea-dashboard.png" alt="Gitea dashboard" />
<h3>Self-Hosted Git</h3>
<p>Gitea hosts infrastructure code, documentation, project files, and portfolio development.</p>
</article>
<article class="card">
<img src="assets/images/portfolio-woodpecker-pipeline.png" alt="Woodpecker successful pipeline" />
<h3>CI/CD Automation</h3>
<p>Woodpecker runs automated pipelines connected to Gitea repositories.</p>
</article>
</div>
</section>
<section id="platform" class="section">
<p class="eyebrow">Platform</p>
<h2>Service Portal</h2>
<div class="card-grid two">
<article class="card">
<img src="assets/images/portfolio-cloud-dashboard-overview.png" alt="Dashy overview" />
<h3>Operations Portal</h3>
<p>Dashy provides quick access to infrastructure, observability, and development services.</p>
</article>
<article class="card">
<img src="assets/images/portfolio-cloud-dashboard-services.png" alt="Dashy services" />
<h3>Service Catalog</h3>
<p>Organized access to security tools, utilities, file management, and public sites.</p>
</article>
</div>
</section>
<section id="recovery" class="section">
<p class="eyebrow">Recovery</p>
<h2>Documentation & Disaster Recovery</h2>
<div class="feature-card">
<img src="assets/images/portfolio-wiki-disaster-recovery.png" alt="Disaster recovery documentation" />
<div> <div>
<h3>Recovery Planning</h3> <h2>One server, treated like a platform.</h2>
<p> <p>
ByteGeist includes documented restore procedures, backup validation, service inventory, Public traffic terminates at Nginx Proxy Manager. Authentik handles identity before
DNS information, recovery priorities, and full environment rebuild planning. requests reach protected services. Metrics, logs, CI, and backups remain separate
concerns, so each can fail or change without taking the whole stack with it.
</p> </p>
</div> </div>
</div> </div>
</section>
<section class="section challenges"> <figure class="architecture-figure">
<p class="eyebrow">Technical Challenges</p> <img src="assets/images/bytegeist-architecture.png" alt="Detailed ByteGeist infrastructure architecture diagram" />
<h2>Problems Solved</h2> <figcaption>Current architecture — updated as services are added or retired.</figcaption>
<div class="challenge-grid"> </figure>
<div>
<h3>OIDC Integration</h3> <div class="principles">
<p>Resolved redirect URI mismatches, user provisioning, and authorization issues.</p> <article>
</div> <span>Access</span>
<div> <h3>Authenticate once</h3>
<h3>Forward Auth</h3> <p>OIDC where supported; forward auth for services that do not speak it natively.</p>
<p>Integrated Authentik Forward Auth with reverse proxy protected services.</p> </article>
</div> <article>
<div> <span>Operations</span>
<h3>Observability</h3> <h3>Make failures visible</h3>
<p>Built centralized metrics and logging using Grafana, Prometheus, Loki, and Alloy.</p> <p>Host and container metrics, centralized logs, and independent uptime checks.</p>
</div> </article>
<div> <article>
<h3>Security Hardening</h3> <span>Recovery</span>
<p>Implemented SSH key-only login, Fail2Ban, CrowdSec, UFW, TLS, and SSO.</p> <h3>Assume the host is replaceable</h3>
</div> <p>Configuration lives in Git. Persistent data is backed up with rebuild notes.</p>
</article>
</div> </div>
</section> </section>
<section class="skills"> <section id="systems" class="systems section-rule">
<h2>Core Skills Demonstrated</h2> <div class="section-heading compact">
<div class="skills-list"> <p class="section-index">02 / Selected systems</p>
<span>Linux Administration</span> <div>
<span>Docker & Compose</span> <h2>The parts I spend time on.</h2>
<span>Reverse Proxies</span> <p>Not a catalog of logos—a record of what is running, why it exists, and what I learned building it.</p>
<span>Networking</span> </div>
<span>TLS / SSL</span>
<span>DNS Management</span>
<span>Identity Management</span>
<span>SSO / OAuth2 / OIDC</span>
<span>Monitoring & Observability</span>
<span>Centralized Logging</span>
<span>CI/CD Automation</span>
<span>Security Hardening</span>
<span>Threat Detection & Response</span>
<span>Backup Strategy</span>
<span>Disaster Recovery</span>
<span>Technical Documentation</span>
</div> </div>
<article class="system-story">
<div class="story-copy">
<p class="story-number">01</p>
<p class="story-label">Observability</p>
<h3>Useful signals before pretty dashboards.</h3>
<p>
Prometheus collects host and container metrics while Loki receives logs through
Grafana Alloy. The dashboards answer practical questions: what is down, what changed,
and which container is consuming the host.
</p>
<ul>
<li>Grafana</li><li>Prometheus</li><li>Loki</li><li>Alloy</li>
</ul>
</div>
<div class="story-images">
<img src="assets/images/portfolio-grafana-operations.png" alt="Grafana infrastructure metrics dashboard" />
<img src="assets/images/portfolio-grafana-logs.png" alt="Centralized container logs in Grafana" />
</div>
</article>
<article class="system-story reverse">
<div class="story-copy">
<p class="story-number">02</p>
<p class="story-label">Identity & security</p>
<h3>One identity layer, fewer exposed edges.</h3>
<p>
Authentik provides SSO, OIDC, forward auth, and 2FA across eleven applications.
CrowdSec watches hostile traffic and creates firewall decisions alongside key-only SSH,
UFW, and TLS.
</p>
<ul>
<li>Authentik</li><li>CrowdSec</li><li>UFW</li><li>Let's Encrypt</li>
</ul>
</div>
<div class="story-images">
<img src="assets/images/portfolio-authentik-applications.png" alt="Applications protected by Authentik" />
<img src="assets/images/portfolio-crowdsec-decisions.png" alt="CrowdSec security decisions" />
</div>
</article>
<article class="system-story">
<div class="story-copy">
<p class="story-number">03</p>
<p class="story-label">Development</p>
<h3>Code and delivery stay in-house.</h3>
<p>
Gitea stores infrastructure code and documentation. Woodpecker runs repository-linked
pipelines, including the build and deployment path for this site.
</p>
<ul>
<li>Gitea</li><li>Woodpecker CI</li><li>Docker</li><li>Git</li>
</ul>
</div>
<div class="story-images">
<img src="assets/images/portfolio-gitea-dashboard.png" alt="Self-hosted Gitea dashboard" />
<img src="assets/images/portfolio-woodpecker-pipeline.png" alt="Successful Woodpecker CI pipeline" />
</div>
</article>
<article class="system-story reverse">
<div class="story-copy">
<p class="story-number">04</p>
<p class="story-label">Platform & recovery</p>
<h3>The boring work is part of the system.</h3>
<p>
Dashy keeps service access legible. The wiki records inventory, DNS, restore order,
backup validation, and the steps required to rebuild the environment from a clean host.
</p>
<ul>
<li>Dashy</li><li>Wiki.js</li><li>Restic</li><li>Runbooks</li>
</ul>
</div>
<div class="story-images">
<img src="assets/images/portfolio-cloud-dashboard-overview.png" alt="ByteGeist internal service portal" />
<img src="assets/images/portfolio-wiki-disaster-recovery.png" alt="ByteGeist disaster recovery runbook" />
</div>
</article>
</section>
<section id="lessons" class="lessons section-rule">
<div class="section-heading compact">
<p class="section-index">03 / Lessons</p>
<div>
<h2>What actually took work.</h2>
</div>
</div>
<div class="lesson-list">
<article>
<span>01</span>
<h3>OIDC is mostly careful bookkeeping.</h3>
<p>Redirect URIs, claims, group mapping, and user provisioning all need to agree across both ends.</p>
</article>
<article>
<span>02</span>
<h3>Backups are unfinished until restore is documented.</h3>
<p>I track data location, dependencies, restore order, DNS, certificates, and validation—not just archive jobs.</p>
</article>
<article>
<span>03</span>
<h3>Observability has to support a decision.</h3>
<p>A smaller dashboard that explains an incident is more useful than a wall of metrics nobody checks.</p>
</article>
<article>
<span>04</span>
<h3>Convenience can weaken the boundary.</h3>
<p>Every exposed service has a cost. SSO, least privilege, and fewer public endpoints keep that cost explicit.</p>
</article>
</div>
</section>
<section class="closing">
<p class="section-index">Project notes</p>
<h2>This environment is still changing.</h2>
<p>
I use ByteGeist to practice the parts of infrastructure work that tutorials tend to skip:
upgrades, failure modes, access policy, noisy logs, and recovery.
</p>
<a class="button primary" href="https://wiki.casko.dev">Open the documentation <span>↗</span></a>
</section> </section>
</main> </main>
<footer> <footer>
<span>ByteGeist Cloud</span> <a class="brand" href="#top">
<p>Built and maintained by Keith Casko</p> <img src="assets/images/bytegeist-logo.png" alt="" />
<span>ByteGeist</span>
</a>
<p>A self-hosted infrastructure project by Keith Casko.</p>
<p>Built with plain HTML and CSS.</p>
</footer> </footer>
</body> </body>
</html> </html>
+551 -337
View File
File diff suppressed because it is too large Load Diff