Migrate devpi from minikube to indri (launchd) #341
1 changed files with 74 additions and 0 deletions
docs: how-to for devpi on indri (launchd)
End-state doc describing devpi as a native LaunchAgent on indri, replacing the minikube StatefulSet. Covers layout, deploy, verify, and version bumps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
commit
ad04f5cfb8
74
docs/how-to/operations/devpi-on-indri.md
Normal file
74
docs/how-to/operations/devpi-on-indri.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
title: Devpi on Indri
|
||||
modified: 2026-04-29
|
||||
last-reviewed: 2026-04-29
|
||||
tags:
|
||||
- how-to
|
||||
- operations
|
||||
---
|
||||
|
||||
# Devpi on Indri
|
||||
|
||||
How devpi (the PyPI caching mirror at `pypi.ops.eblu.me`) is deployed on indri as a launchd-managed native service. Replaces the prior minikube StatefulSet.
|
||||
|
||||
## Why native, not Kubernetes
|
||||
|
||||
Devpi has no runtime dependencies beyond a Python interpreter, a writable directory, and outbound HTTPS to upstream PyPI. Running it on indri natively removes a layer of operational complexity, frees minikube resources, and decouples this critical-path tooling (used by every Python build, including `mise run docs-mikado` itself) from cluster health.
|
||||
|
||||
## Layout
|
||||
|
||||
| Concern | Path / detail |
|
||||
|---|---|
|
||||
| Service binary | `/Users/erichblume/devpi/venv/bin/devpi-server` |
|
||||
| Server-dir (data) | `/Users/erichblume/devpi/server-dir/` |
|
||||
| Logs | `/Users/erichblume/Library/Logs/mcquack.devpi.{out,err}.log` |
|
||||
| LaunchAgent label | `mcquack.eblume.devpi` |
|
||||
| LaunchAgent plist | `~/Library/LaunchAgents/mcquack.eblume.devpi.plist` |
|
||||
| Listen address | `127.0.0.1:3141` (loopback only) |
|
||||
| Public URL | `https://pypi.ops.eblu.me` (via Caddy reverse proxy) |
|
||||
| Root password secret | 1Password item `devpi`, field `root password` |
|
||||
|
||||
The venv is built fresh by ansible from a pinned `devpi-server` and `devpi-web` version; bumping versions is a config change in `ansible/roles/devpi/defaults/main.yml`.
|
||||
|
||||
## Deploy
|
||||
|
||||
```fish
|
||||
mise run provision-indri -- --tags devpi
|
||||
```
|
||||
|
||||
Ansible will:
|
||||
|
||||
1. Fetch the root password from 1Password (in playbook `pre_tasks`)
|
||||
2. Create the venv at `~/devpi/venv` if absent and install/upgrade `devpi-server` + `devpi-web` to the pinned versions
|
||||
3. Initialize the server-dir (only on first run, when `.serverversion` is missing)
|
||||
4. Render and load the LaunchAgent plist
|
||||
5. Restart the service if the plist or config changed
|
||||
|
||||
Caddy already proxies `pypi.ops.eblu.me` → `127.0.0.1:3141`; nothing else routes traffic.
|
||||
|
||||
## Verify
|
||||
|
||||
```fish
|
||||
ssh indri 'launchctl list mcquack.eblume.devpi'
|
||||
curl -fsS https://pypi.ops.eblu.me/+api | jq
|
||||
uv pip install --index-url https://pypi.ops.eblu.me/root/pypi/+simple/ requests
|
||||
```
|
||||
|
||||
## Logs
|
||||
|
||||
```fish
|
||||
ssh indri 'tail -f ~/Library/Logs/mcquack.devpi.err.log'
|
||||
```
|
||||
|
||||
## Bumping devpi versions
|
||||
|
||||
Edit `devpi_server_version` / `devpi_web_version` in `ansible/roles/devpi/defaults/main.yml`, then re-run the playbook with `--tags devpi`. The role rebuilds the venv in-place; the server-dir survives.
|
||||
|
||||
## Backup
|
||||
|
||||
The server-dir is included in the borgmatic file backup that already covers `~erichblume/`. Devpi indexes are recoverable from upstream PyPI on a fresh start; only the local index (`root/dev`) is unique state.
|
||||
|
||||
## Related
|
||||
|
||||
- [[restart-indri]] — devpi is one of the LaunchAgents to stop on graceful shutdown
|
||||
- [[connect-to-postgres]] — pattern for indri-native services (different stack, similar shape)
|
||||
Loading…
Add table
Add a link
Reference in a new issue