GitOps repository for personal infrastructure management
  • Nix 32.5%
  • Jinja 21.5%
  • Python 17.9%
  • Shell 11.8%
  • Go 8.1%
  • Other 8.2%
Find a file
Erich Blume c86b5d7772
All checks were successful
Build Container / detect (push) Successful in 3s
Build Container / build-dagger (navidrome) (push) Successful in 22m26s
Native Dagger container builds + Navidrome v0.61.1 (#330)
## Summary
- Move Dagger module from `.dagger/` to repo root (`src/blumeops/`), rename `blumeops-ci` → `blumeops`
- Replace opaque `docker_build()` with native Dagger pipelines that surface full build errors per step
- Migrate navidrome as the first container (`containers/navidrome/container.py`)
- Upgrade navidrome from v0.60.3 to v0.61.1 (major artwork overhaul, SQLite FTS5 search, server-managed transcoding)
- Add `dagger call container-version` for CI version extraction without Dockerfile parsing
- All mise tasks (`container-list`, `container-version-check`, `container-build-and-release`) updated for hybrid mode
- Legacy `docker_build()` fallback preserved for all other containers

## Motivation
When navidrome v0.61.0 added a new Go build tag (`sqlite_fts5`), `docker_build()` showed only "exit code: 1". We had to run `docker build --progress=plain` manually to find `undefined: buildtags.SQLITE_FTS5`. Native Dagger pipelines show the full error inline.

## Container build dispatch needed
After merge, dispatch container build for navidrome:
```
mise run container-build-and-release navidrome --ref 470b4bd
```

## Deploy steps
1. Wait for container build to complete
2. Back up navidrome-data PVC (non-reversible DB migrations)
3. `argocd app set navidrome --revision main && argocd app sync navidrome`
4. Verify at https://dj.ops.eblu.me

## Future
Remaining containers migrate incrementally in follow-up PRs using the same pattern.

Reviewed-on: #330
2026-04-11 17:11:56 -07:00
.claude Remove doc-reviewer agent 2026-03-30 16:12:48 -07:00
.forgejo/workflows Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
.github
ansible Deploy Paperless-ngx document management (#328) 2026-04-08 17:54:12 -07:00
argocd Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
containers Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
docs Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
fly Pin Fly.io Tailscale to v1.94.1 to fix MagicDNS regression in v1.96.5 2026-04-10 19:32:38 -07:00
mise-tasks Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
nixos/ringtail Fix flake-update pipeline and update ringtail flake inputs 2026-04-06 08:27:31 -07:00
pulumi Expose Forgejo publicly at forge.eblu.me (#278) 2026-03-03 08:40:41 -08:00
src/blumeops Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
utils/qart Add QArt Tuner: QR code art generator with interactive web UI 2026-03-27 15:33:36 -07:00
.ansible-lint
.gitattributes Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
.gitignore Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
.yamllint.yaml Allow implicit octals in yamllint and normalize k8s mode values 2026-03-03 13:10:44 -08:00
Brewfile
CHANGELOG.md Update docs release to v1.15.4 2026-04-06 07:53:54 -07:00
CLAUDE.md Build custom Kingfisher container from sporked deploy branch (#318) 2026-03-30 06:34:49 -07:00
compensating-controls.yaml Review compensating control: tailscale-network-isolation 2026-04-06 10:35:13 -07:00
dagger.json Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
LICENSE
mise.toml Upgrade Dagger engine from v0.20.0 to v0.20.1 2026-03-06 20:41:02 -08:00
prek.toml Add Kingfisher secret scanner to prek hooks 2026-03-28 21:07:07 -07:00
pyproject.toml Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
README.md Remove suggestion to run prek manually from README 2026-03-05 08:15:25 -08:00
service-versions.yaml Native Dagger container builds + Navidrome v0.61.1 (#330) 2026-04-11 17:11:56 -07:00
towncrier.toml
update-loki-3.6.7.infra.md Update loki to 3.6.7 (#302) 2026-03-20 16:02:28 -07:00

blumeops

aka "Blue Mops"

Tools and configuration for Erich Blume's personal infrastructure, orchestrated across a Tailscale tailnet.

This is a homelab, but it's also a testing ground for AI-assisted infrastructure development. Much of this codebase was co-authored with Claude Code, and the repo places heavy emphasis on documentation, process, and change classification to make that collaboration work well. I don't know entirely how I feel about LLMs in our current era (there are real concerns about how training data is sourced and energy subsidy) but it felt important to learn how to work with these tools.

The full documentation is published at docs.eblu.me and lives in the docs/ directory, structured around the Diataxis framework and designed to be compatible with Obsidian/Obsidian.nvim.

What runs here

Services are a mix of Kubernetes pods (managed by ArgoCD), macOS LaunchAgent services (managed by Ansible), and NixOS systemd services (managed by Nix flakes), all connected via Tailscale:

  • Indri (Mac Mini M1) - primary server. Most services run in Minikube via ArgoCD; Forgejo, Caddy, and others run natively as LaunchAgent services via Ansible.
  • Ringtail (NixOS desktop, RTX 4080) - GPU workloads (Frigate NVR, Authentik SSO) on k3s, plus NixOS systemd services.
  • Sifaka (Synology NAS) - backup target and bulk storage.

Notable services include Grafana/Prometheus/Loki observability, Immich photos, Jellyfin media, Forgejo git forge, a Zot container registry, and more. Public access is routed through a Fly.io proxy; everything else is tailnet-only.

Project structure

ansible/            Ansible playbooks and roles (indri, sifaka)
argocd/apps/        ArgoCD Application definitions
argocd/manifests/   Kubernetes manifests per service
containers/         Custom container builds (Dockerfile + Nix)
docs/               Diataxis documentation (published at docs.eblu.me)
fly/                Fly.io public proxy configuration
mise-tasks/         Operational scripts run via mise
nixos/              NixOS configuration for ringtail
pulumi/             Pulumi IaC (Tailscale ACLs, Gandi DNS)
.dagger/            Dagger CI pipelines
.forgejo/           Forgejo Actions CI/CD workflows

Getting started

You'll need Homebrew and mise:

brew bundle                    # install CLI tools (argocd, tea, flyctl, etc.)
mise install                   # install managed toolchains (ansible, pulumi, dagger, etc.)
prek install                    # set up git hooks

Git hooks (via prek) enforce secret scanning (TruffleHog), linting, formatting, and custom checks like doc link validation and the Mikado branch invariant. They run automatically on git commit.

Operational tasks are driven through mise. Run mise tasks to see what's available. Key examples:

mise run provision-indri       # deploy to indri via Ansible
mise run services-check        # verify service health
mise run container-list        # list tracked container images

AI-assisted development

This repo is designed to be worked on by both humans and AI agents. The CLAUDE.md file provides instructions for Claude Code, and the docs/tutorials/ai-assistance-guide.md explains the full workflow.

Changes are classified before starting work:

  • C0 - quick fixes, committed directly to main
  • C1 - feature branch + PR, documentation written before code
  • C2 - multi-phase work using the Mikado method for dependency tracking

See the agent change process for details.

License

GPLv3