awkto
Home lab tinkerer & platform engineer. Home lab tinkerer and platform engineer. Small open-source tools for self-hosting, DNS, secrets and platform plumbing.
Recent writing
- Run Claude Code in CI on your subscription, not the metered API — — Running Claude Code headless in a pipeline almost always reaches for an ANTHROPIC_API_KEY — which bills pay-per-token, separate from the Max plan you're already paying for. But Claude Code has a second auth mode that draws on the subscription instead. It's one env var and a token you generate once. Here's the switch, and the edges that come with drawing CI usage from a personal plan.
- Email on a custom domain without running a mail server — — I wanted me@awkto.dev to just work — receive into an inbox I already read, and reply from it too — without standing up Postfix, paying for a mailbox, or babysitting a spam reputation. It turned out to be a forwarding service for inbound and a relay bolted onto Gmail for outbound: two free tiers, zero servers. Here's exactly how the stack fits together and where its edges are.
- Three ways to build an agent (and why I picked the middle one) — — I built an AI teammate that lives inside my GitLab. The hard question was never 'which model' — it was 'who runs the loop.' There are exactly three answers, and the difference between them is mostly about what leaves your network.
- GitLab with Object Storage on DigitalOcean or Cloudflare — — GitLab's object-storage docs lean on AWS S3 and GCS examples — fine for a company, but for a home lab those clouds are expensive and genuinely dangerous (egress fees and runaway costs). DO Spaces and Cloudflare R2 are flat-rate, S3-compatible, and boring in the best way. Here's the gitlab.rb that actually works on both, including the R2 quirks the docs don't mention.
- Making Bitwarden non-interactive for an AI agent — — Both Bitwarden CLIs assume a human is sitting there to type the master password, the API client_secret, and the 2FA code. For an AI agent doing bulk vault edits, every prompt is a deadlock. The fix is one specific insight: `rbw` asks for every secret through pinentry, and pinentry is a protocol I can implement. A 30-line bash script that routes each prompt to OpenBao turns rbw into a fully unattended tool.