You Don’t Need Kubernetes

Side Projects on One Linux Server

Brian "bex" Exelbierd 🌐 www.bexelbie.com βœ‰οΈ [email protected] @[email protected]
--- # The Side Project Trap ![bg right:34% fit](yak-shave.jpg) | "Best Practice" Stack | What You Actually Need | |:--|:--| | Build for scale πŸš€πŸš€πŸš€ | Build for reality | | Kubernetes cluster | One server | | CI/CD pipeline for infra | A config file | | HashiCorp Vault | Your password manager | | Grafana + Prometheus | Something you already run | | Hours of maintenance | Hours on your actual project | --- # PuzzleSecretary.com A web service for tracking social game scores - I play Wordle, Connections, Strands, etc. with friends across time zones - We share scores in a Signal chat - I can track how my friend Peter in the UK is doing β€” we play at similar times - But when the US wakes up, it becomes a flood of scores I can't follow - PuzzleSecretary collects scores from Signal and WhatsApp, builds personal leaderboards and group comparisons --- # Don't Solve Problems You Don't Have
graph LR
    S[Signal] -->|~msgs/day| F[Flask]
    W[WhatsApp] -->|~msgs/day| F
    F -->|INSERT| DB[(SQLite)]
    DB -->|SELECT| F
    F -->|leaderboards| B[Browser]

    style DB fill:#f9f,stroke:#333
Human players around the world β†’ low-frequency writes Friends checking leaderboards β†’ low-frequency reads SQLite excels at both. One VM. Done. --- # What Do I Already Have or Know? ![bg right:30% fit](thinking.jpg) The recurring question behind every decision --- # The OS: Flatcar Linux ![bg right:35% fit](flatcar-logo.svg) - Immutable β€” dm-verity protected `/usr`, no drift - Auto-updates β€” atomic, whole-OS, rollback = reboot - No `apt install` β€” all your dependencies go in containers - Treat the OS like firmware: provision once, update automatically - I work with the Flatcar engineers β€” virtual throat to choke **My Flatcar 101 talk is today @ 5pm in Track III** --- # Containers: Rootless Podman Quadlets
```ini [Container] Image=ghcr.io/bexelbie/puzzlesecretary:latest Label=io.containers.autoupdate=registry Volume=/home/app/leaderboard:/data:Z EnvironmentFile=/home/app/env PublishPort=127.0.0.1:5000:5000 [Service] Restart=always ExecStartPre=/opt/op-secret-manager/op-secret-manager ExecStopPost=/opt/op-secret-manager/op-secret-manager --cleanup [Install] WantedBy=default.target ```
- Quadlet file = container described as a systemd service - Rootless = unprivileged host user. Break out? You're still nobody. --- # Secrets: Your Password Manager is Already a Vault
graph LR
    A[1Password] -->|API| B[OP Secret Manager]
    B -->|files| C[/run/secrets/]
    B -->|env vars| D[Quadlet .env files]
    C --> E[Containers]
    D --> E
    style A fill:#0572ec,stroke:#333,color:#fff
    style E fill:#f9f,stroke:#333
- Your password manager stores credentials, notes, files β€” and has an API - Applications understand files and environment variables - Connect the two: pre-exec in systemd downloads secrets before the service starts - I also store configuration as 1Password notes β€” centralized secrets AND config - managed with github.com/bexelbie/op-secret-manager --- # Network: Zero Open Ports ![bg right:45% fit](inbound-traffic.jpg) | Inbound Traffic | How | |:--|:--| | Web (puzzlesecretary.com) | Cloudflare Tunnel | | SSH (management) | Tailscale | | Open ports on the VM | **None** | --- # Monitoring and Alerting ## Why Not Grafana? 1. I don't want to run more infrastructure just for running infrastructure 2. I am not going to look at a dashboard --- # The Pipeline: Telegraf β†’ MQTT β†’ ???
graph LR
    subgraph VM ["Azure VM"]
        C[Containers] -->|metrics| T[Telegraf]
        T -->|publish| M[MQTT messages]
    end
    M --> Q["???"]
    style VM fill:#e8f4f8,stroke:#333
    style T fill:#4b275f,stroke:#333,color:#fff
    style Q fill:#ffd700,stroke:#333
- Telegraf: container that gathers system and custom metrics - MQTT: lightweight message protocol - Metrics flow out to ... something that stores time-series data and alerts --- # ![h:48](homeassistant.png) Home Assistant ![bg right:40% fit](monitoring.png) We think of it as "turn on the lights." It's actually: track a value, store it, graph it, alert on it. - Battery levels, temperature, meter readings β€” all time-series data - Long-term statistics engine built in - Already running MQTT at my house for unrelated reasons - I use this pattern for two servers now --- # Alerting: Home Assistant Knows How to Reach You Home Assistant can: - Push a notification to your phone - Override silent mode for critical alerts - Add an item to your to-do list - Put a message on an e-ink display - It could even flash the lights and pause the movie if needed ![w:768](alert.png) --- # The Architecture One VM. Six connections to things I already had.
graph LR
    MO[Montastic] -.->|probe| CC[Cloudflare]
    CC -->|tunnel| VM[VM: Flatcar + Quadlets]
    VM -->|fetch secrets| OP[1Password]
    VM -->|MQTT/Tailscale| HA[Home Assistant]
    HA -->|alerts| PH[Phone]
    LAP[Laptop] -->|SSH/Tailscale| VM
--- # Day 2: What Maintenance Looks Like | When | What | How long | |:--|:--|:--| | Most days | Nothing. It runs itself. | 0 min | | Wednesday | HA says "3 containers need updates" β†’ SSH in, `podman auto-update` | 5 min | | When I ship a feature | Push release to Github, container auto built then load it | 15 min | | Something breaks | HA alerts my phone, I SSH in and look at logs | varies | | OS update | Flatcar stages it, reboots Wednesday morning | 0 min | --- # The Recurring Question ![bg right:30% fit](thinking.jpg) Every decision followed the same pattern: | I need... | I already have or know ... | |:--|:--| | A server OS | Flatcar (from my day job) | | Container management | Podman Quadlets β†’ systemd | | A secrets vault | 1Password (family plan) | | Secure networking | Cloudflare + Tailscale | | Monitoring | Home Assistant + MQTT | | Alerting & notifications | Home Assistant automations | | External uptime check | Montastic (free) | --- # Adapt the Principle, Not the Stack You don't need my specific tools. You need the question. - Flatcar β†’ Fedora CoreOS, NixOS, whatever immutable OS fits - 1Password β†’ Bitwarden, any password manager with an API - Home Assistant β†’ Uptime Kuma, anything that tracks values and alerts - Cloudflare Tunnel β†’ ngrok, bore, any reverse tunnel - The principle: stretch what you already know and pay for --- # Thank You **Come to Flatcar 101** β†’ Today @ 5pm, Track III **Try PuzzleSecretary** β†’ puzzlesecretary.com
Brian "bex" Exelbierd 🌐 www.bexelbie.com βœ‰οΈ [email protected] @[email protected]
---