361 lines
10 KiB
Vue
Raw Normal View History

2025-12-18 01:13:04 -03:00
<template>
<div class="page">
<section class="card about">
<div class="left">
2025-12-19 16:53:29 -03:00
<div class="portrait">
<img src="@/assets/profile-avatar.jpg" alt="Brad Stein" />
</div>
2025-12-18 01:13:04 -03:00
<div class="contact">
<div class="name">Brad Stein</div>
<div class="role">Senior Software Development Engineer </div>
<div class="role">SDET/ DevOps / Platform Tooling</div>
<div class="meta">US Citizen · Remote</div>
<div class="links">
<a href="https://www.linkedin.com/in/steinbradley/" target="_blank" rel="noreferrer">LinkedIn</a>
<a href="https://scm.bstein.dev/bstein" target="_blank" rel="noreferrer">Gitea</a>
<a href="https://metrics.bstein.dev" target="_blank" rel="noreferrer">Metrics</a>
<a href="mailto:brad@bstein.dev">brad@bstein.dev</a>
</div>
</div>
</div>
<div class="right">
<h1>About Me</h1>
<div class="copy">
<p>
Senior Backend &amp; DevOps engineer focused on making systems reliable. I build Python-driven tools on Linux, Kubernetes, and CI/CD
to keep distributed systems healthy.
</p>
<p>
I like simplifying environments and release pipelines so teams can ship and operate confidently. Recent work: platform tooling for a
Flux-managed Kubernetes microservice stack on the U.S. Space Forces PTES program.
</p>
<p>
My projects and dashboards run on my local <span class="mono">k3s</span>: see
<a href="https://scm.bstein.dev/bstein" target="_blank" rel="noreferrer">scm.bstein.dev</a> and
<a href="https://metrics.bstein.dev" target="_blank" rel="noreferrer">metrics.bstein.dev</a>.
</p>
</div>
<div class="highlights">
<div v-for="skill in skills" :key="skill" class="pill mono">{{ skill }}</div>
</div>
</div>
</section>
<section class="card">
<div class="section-head">
<h2>Experience</h2>
<span class="pill mono">Summary</span>
</div>
<div class="timeline">
<div v-for="item in timeline" :key="item.id" class="entry">
<div class="dot"></div>
<div>
<div class="entry-title">{{ item.title }}</div>
<div class="entry-sub">{{ item.company }} · {{ item.dates }}</div>
<ul>
<li v-for="point in item.points" :key="point">{{ point }}</li>
</ul>
</div>
</div>
</div>
<div class="divider"></div>
<p class="note">
<a href="https://www.linkedin.com/in/steinbradley/" target="_blank" rel="noreferrer">
Full role history and exact dates are on LinkedIn.
</a>
</p>
</section>
<section class="card">
<div class="section-head">
2026-01-13 08:53:13 -03:00
<h2>Titan Lab</h2>
2025-12-18 01:13:04 -03:00
<span class="pill mono">atlas + oceanus</span>
</div>
<div class="copy">
<p>
2026-01-13 08:53:13 -03:00
The Titan Lab is my 26-node (and growing) homelab with a production mindset: security, monitoring, and repeatable changes. The core is
<span class="mono">Atlas</span>, a GitOps-managed <span class="mono">k3s</span> cluster where services are reconciled by
2025-12-18 01:13:04 -03:00
<span class="mono">Flux</span>.
</p>
<p>
2026-01-13 08:53:13 -03:00
<span class="mono">Atlas</span> is my attempt to fully replace all online services that I need or use with self-hosted versions. I care
deeply about security both for the lab and the cluster and personally. My first hosted services was <span class="mono">VaultWarder</span>
but now the cluster hosts everything from email to ai. In my freetime, I'm always working on <span class="mono">Atlas</span> with small
services or organization improvements to make it better and cleaner and cooler.
</p>
<p>
<span class="mono">Oceanus</span> is intentionally separated host for validator workloads while still feeding data back into the same
observability stack. SUI is a crypto currency I follow and believe in and so <span class="mono">Oceanus</span> is in my lab and is dedicated
hardware to extend their infrastructure and make the SUI project more resilient.
2025-12-18 01:13:04 -03:00
</p>
</div>
</section>
</div>
</template>
<script setup>
const skills = [
"Python",
"Linux",
2026-01-13 08:53:13 -03:00
"Kubernetes (k3s/k8s)",
2025-12-18 01:13:04 -03:00
"Containers (Docker/OCI)",
"GitOps (Flux)",
"CI/CD (Jenkins)",
"Release gating",
"Test automation",
"Keycloak / OIDC",
"Grafana + VictoriaMetrics",
"Traefik ingress",
"Longhorn storage",
"Go",
"Rust",
"Bash",
"Terraform",
"SQL",
];
const timeline = [
{
id: "actalent-boeing-ptes",
title: "Senior Software Development Engineer in Test",
company: "Boeing (Actalent contract)",
dates: "Sep 2023 Oct 2025",
points: [
"Built internal tools and infrastructure around a Kubernetes microservice platform (PTES).",
"Created Lanterna, a visualization tool mapping service and environment relationships from a Flux-controlled monorepo.",
"Designed Jenkins promotion workflows and test-gating pipelines to move builds safely through environments.",
"Built TaskWatcher for drift protection and orchestration of non-Kubernetes systems, including capture of transient crypto artifacts.",
],
},
{
id: "titan-lab-architect",
title: "Titan Lab Architect",
company: "Titan Lab (personal platform)",
dates: "Apr 2020 Present",
points: [
2026-01-13 08:53:13 -03:00
"Operate a mixed arm64/amd64 environment with GitOps (Gitea -> Jenkins -> Harbor -> Flux).",
"Centralized identity with Keycloak and front services via Traefik ingress.",
2025-12-18 01:13:04 -03:00
"Run tiered Longhorn storage: astreae (system) and asteria (user).",
2026-01-13 08:53:13 -03:00
"Build observability with Grafana + VictoriaMetrics and OpenSearch dashboards around real service health and log tracking.",
"Audio, video, and text communication on a Matrix-LiveKit-Coturn-Element stack with mobile compatibility and AI chat integration.",
"Video streaming of home movies via Jellyfin and instant uploading/publishing with Pegasus.",
"Host crypto projects with a XRM node and a SUI validator.",
"Has a knowledge base about the cluster itself for AI bot awareness.",
"Vault based secret management - no critical information in Kubernetes secrets.",
2025-12-18 01:13:04 -03:00
],
},
{
id: "ibm-sdet",
title: "Software Development Engineer in Test",
company: "IBM",
dates: "Mar 2020 May 2023",
points: [
"Authored and planned system and end-to-end integration tests using Go, Terraform, Python, and Bash.",
"Monitored critical API endpoints with Zabbix and worked incident-style issues end to end.",
"Supported platform testing for the Madrid Data Center rollout.",
],
},
{
id: "softlayer-ibmcloud-sdet",
title: "Software Development Engineer in Test",
company: "SoftLayer / IBM Cloud (TekSystems Contract)",
dates: "Nov 2018 Mar 2020",
points: [
"Built automated end-to-end tests in Go and Python across REST and SOAP APIs.",
"Worked across frontend and backend efforts (Vue, WordPress, Docker, MySQL/Postgres).",
"Used Jenkins + Splunk/Kibana to diagnose failures and produce coverage-focused test reports.",
],
},
{
id: "unifocus-survey-programmer",
title: "Survey Programmer",
company: "UniFocus",
dates: "Aug 2014 Nov 2018",
points: [
"Wrote SQL-driven survey sites and reporting logic; customized sites via CSS and JavaScript.",
"Built Python and VBA automation tools to reduce manual work for teams and business partners.",
"Won UniFocus Excellence Award (2015) and Innovation Award (2016).",
],
},
{
id: "magic-aire-engineering-assistant",
title: "Engineering Assistant",
company: "United Electric Company - Magic Aire",
dates: "Apr 2011 Aug 2014",
points: [
"Wrote and maintained VBA tools for internal use, including interpolators and data-entry utilities.",
"Supported mechanical engineering work in SolidWorks (drawing modernization and component standardization).",
],
},
];
</script>
<style scoped>
.page {
max-width: 1000px;
margin: 0 auto;
padding: 32px 22px 72px;
}
.about {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 18px;
}
.portrait {
width: 120px;
height: 120px;
flex: 0 0 120px;
aspect-ratio: 1 / 1;
2025-12-18 01:13:04 -03:00
border-radius: 50%;
2025-12-19 16:53:29 -03:00
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.12);
2025-12-18 01:13:04 -03:00
display: grid;
place-items: center;
2025-12-19 16:53:29 -03:00
background: linear-gradient(135deg, rgba(0, 229, 197, 0.5), rgba(127, 124, 255, 0.45));
}
.portrait img {
width: 100%;
height: 100%;
object-fit: cover;
2025-12-18 01:13:04 -03:00
}
.left {
display: flex;
align-items: center;
gap: 14px;
}
.contact .name {
font-weight: 800;
color: var(--text-strong);
}
.contact .role {
color: var(--text-muted);
}
.contact .meta {
color: var(--text-muted);
font-size: 13px;
margin-top: 2px;
}
.badges {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: 10px;
}
.links {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-top: 8px;
}
.links a {
color: var(--accent-cyan);
text-decoration: none;
}
.links a:hover {
color: var(--accent-rose);
}
.right h1 {
margin: 0 0 8px;
}
.section-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
.copy {
color: var(--text-muted);
}
.copy p {
margin: 0 0 10px;
line-height: 1.55;
}
.copy p:last-child {
margin-bottom: 0;
}
.highlights {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: 12px;
}
.note {
color: var(--text-muted);
margin: 0;
}
.note a {
color: var(--text-muted);
text-decoration: none;
border-bottom: 1px dashed rgba(255, 255, 255, 0.18);
padding-bottom: 1px;
}
.note a:hover {
color: var(--accent-cyan);
border-bottom-color: rgba(0, 229, 197, 0.5);
}
.timeline {
display: grid;
gap: 12px;
margin-top: 8px;
}
.entry {
display: grid;
grid-template-columns: auto 1fr;
gap: 10px;
}
.dot {
width: 14px;
height: 14px;
border-radius: 50%;
border: 2px solid var(--accent-cyan);
margin-top: 6px;
}
.entry-title {
font-weight: 800;
}
.entry-sub {
color: var(--text-muted);
margin-bottom: 4px;
}
ul {
margin: 0;
padding-left: 16px;
color: var(--text-muted);
}
@media (max-width: 820px) {
.about {
grid-template-columns: 1fr;
}
.left {
justify-content: flex-start;
}
}
</style>