## Summary Devpi was crash-looping under memory pressure on the minikube StatefulSet, breaking the Python toolchain across the repo (`mise run docs-mikado`, `prek`, every `uv pip install`). It moves to indri as a native LaunchAgent. ## What changed - **New ansible role** `ansible/roles/devpi/`: installs `devpi-server` + `devpi-web` into a uv-managed venv, initializes the server-dir on first run via 1Password root password, runs as a LaunchAgent (`mcquack.eblume.devpi`) bound to `127.0.0.1:3141`. Bootstraps from upstream PyPI (so devpi can install itself on a fresh box). - **Caddy**: `pypi.ops.eblu.me` now proxies to `http://localhost:3141`. - **Playbook**: `indri.yml` gains pre_tasks for the root password and the new role. - **service-versions.yaml**: devpi flipped from `type: argocd` to `type: ansible`. - **ArgoCD**: removed `apps/devpi.yaml` and `manifests/devpi/`. The in-cluster Application, namespace, and PVC have been deleted. - **Docs**: new how-to `docs/how-to/operations/devpi-on-indri.md`; `restart-indri.md` lists devpi in the LaunchAgent stop list. ## Already deployed (live on indri) - Service running: `launchctl list mcquack.eblume.devpi` → PID 53888 - `curl https://pypi.ops.eblu.me/+api` returns 200 ✅ - `mise run docs-mikado` works again ✅ - 1.0G of cached PyPI data was migrated from the PVC to `~erichblume/devpi/server-dir/` - Minikube namespace and PVC fully reclaimed ## Test plan - [ ] `mise run services-check` (after merge) - [ ] CI workflows that use devpi succeed - [ ] No regressions in tools that depend on `pypi.ops.eblu.me` (prek, uv-script tasks, dagger pipelines) ## Context This is the C1 prelude to a planned C2 chain (`mikado/retire-minikube-indri`) to retire minikube on indri entirely. Doing devpi as a standalone C1 was the right call because (a) it was urgent — it was breaking the toolchain — and (b) it shakes out the migration recipe before we commit to a multi-leaf chain. Reviewed-on: #341
1.7 KiB
1.7 KiB
| title | modified | last-reviewed | tags | ||
|---|---|---|---|---|---|
| Devpi | 2026-04-29 | 2026-04-29 |
|
devpi (PyPI Proxy)
PyPI caching proxy and private package index. Runs natively on indri as a LaunchAgent (not in-cluster). See devpi-on-indri for deploy and operations.
Quick Reference
| Property | Value |
|---|---|
| URL | https://pypi.ops.eblu.me |
| Listen | 127.0.0.1:3141 (loopback only; reached via Caddy) |
| Service | LaunchAgent mcquack.eblume.devpi on indri |
| Server-dir | /Users/erichblume/devpi/server-dir/ |
| Runtime | uv-managed venv at /Users/erichblume/devpi/venv/ |
| Ansible role | ansible/roles/devpi/ |
| Versions | Pinned in ansible/roles/devpi/defaults/main.yml (devpi_server_version, devpi_web_version) |
Indices
| Index | Purpose |
|---|---|
root/pypi |
PyPI mirror/cache (auto-created by devpi-init) |
eblume/dev |
Private packages (inherits from root/pypi) |
Credentials
Root password stored in 1Password (blumeops vault, item devpi, field root password). Fetched via op read in the ansible/playbooks/indri.yml pre_tasks and passed to the role on first init.
Backup
The server-dir is not backed up. The PyPI cache (+files/) is re-fetchable from upstream on first request. The local eblume/dev index metadata is small but also not critical to retain — packages can be republished from source. If retention becomes important, add /Users/erichblume/devpi/server-dir/ to borgmatic_source_directories.
Related
- devpi-on-indri — Deploy, verify, and version-bump procedures
- use-pypi-proxy — Client configuration and package uploads
- 1password — Secrets management