blumeops/docs/zk/1768457769-LOCK.md
Erich Blume b8104d75ad Move zk cards to docs/zk/ for documentation restructuring (#84)
## Summary
- Move all existing zettelkasten cards from `docs/` to `docs/zk/` as a temporary holding area
- Update `zk-docs` mise task to look in the new location
- Add `docs/README.md` explaining the Diataxis-based restructuring plan and target audiences

## Context
This is phase 1 of a multi-phase documentation restructuring effort. The goal is to reorganize docs to follow the Diataxis framework while serving multiple audiences:
1. Erich (owner) - knowledge graph/zk
2. Claude/AI agents - memory and context enrichment
3. New external readers - high-level overview
4. Potential operators/contributors - onboarding
5. Replicators - people wanting to duplicate the approach

## Testing
- [x] Verified `mise run zk-docs` still works with the new path
- [x] Updated obsidian.nvim config (in ~/.config/nvim) to point to new path

## Note
The obsidian.nvim config change is outside this repo but was made as part of this work.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/84
2026-02-03 09:13:50 -08:00

3.8 KiB

id aliases tags
1768457769-LOCK
pypi
devpi
blumeops

PyPI / devpi Management Log

PyPI caching proxy running in Kubernetes (minikube on indri) via devpi-server.

Service Details

  • URL: https://pypi.tail8d86e.ts.net
  • Namespace: devpi
  • Image: registry.tail8d86e.ts.net/blumeops/devpi:latest (custom image with devpi-server + devpi-web)
  • ArgoCD app: devpi
  • Storage: 50Gi PVC

Useful Commands

# View logs
kubectl --context=minikube-indri -n devpi logs -f statefulset/devpi

# Restart pod
kubectl --context=minikube-indri -n devpi rollout restart statefulset/devpi

# Check health
curl https://pypi.tail8d86e.ts.net/+api

# Sync from ArgoCD
argocd app sync devpi

ArgoCD Management

Devpi is deployed via ArgoCD from argocd/manifests/devpi/:

  • statefulset.yaml - StatefulSet with 50Gi PVC
  • service.yaml - ClusterIP service
  • ingress-tailscale.yaml - Tailscale Ingress for external access
  • Dockerfile - Custom image with startup script
  • start.sh - Auto-initialization script

Users and Indices

Structure

  • root/pypi - PyPI mirror/cache (auto-created)
  • eblume/dev - Private packages index (inherits from root/pypi)

Creating a User and Index

# Login as root
uvx devpi use https://pypi.tail8d86e.ts.net
uvx devpi login root

# Create user (prompts for password - store in 1Password)
uvx devpi user -c USERNAME email=EMAIL

# Create index inheriting from PyPI mirror
uvx devpi index -c USERNAME/dev bases=root/pypi

Uploading Packages (with uv)

# Store credentials (one-time, prompts for username/password)
uv auth login https://pypi.tail8d86e.ts.net

# Build and publish
cd ~/code/personal/your-package
uv build
uv publish --publish-url https://pypi.tail8d86e.ts.net/eblume/dev/

Note: The "trusted publishing failed" warning is expected (devpi doesn't support OIDC).

Uploading Packages (with devpi-client)

# Login as the user
uvx devpi login USERNAME

# Use the index
uvx devpi use eblume/dev

# Upload from project directory
uvx devpi upload

Client Configuration

On workstations, configure pip to use the proxy.

pip.conf (~/.config/pip/pip.conf):

[global]
index-url = https://pypi.tail8d86e.ts.net/root/pypi/+simple/
trusted-host = pypi.tail8d86e.ts.net

After creating/editing, track with chezmoi:

chezmoi add ~/.config/pip/pip.conf

Credentials

  • Root password stored in 1Password (blumeops vault)
  • Injected into k8s via devpi-root secret from secret-root.yaml.tpl

Backup

Private packages (eblume/dev index) are stored in the devpi PVC. The PyPI mirror cache (root/pypi) is not backed up as it can be re-fetched.

TODO: Add devpi PVC backup to borgmatic once k8s volume backup strategy is established.

Log

Mon Jan 20 2026

  • Migrated to Kubernetes (Phase 5 of k8s migration)
  • Custom container image with devpi-server + devpi-web + auto-init startup script
  • StatefulSet with 50Gi PVC for data persistence
  • Tailscale Ingress at pypi.tail8d86e.ts.net
  • Root password from 1Password secret, auto-initialized on first run
  • Verified pip caching proxy and mcquack package upload
  • Key learnings:
    • Minikube CRI-O can't resolve Tailscale hostnames - added registry mirror config
    • devpi-web Whoosh indexer needs ~2Gi during initial PyPI index build
    • Kubernetes auto-sets DEVPI_PORT for service discovery - renamed to DEVPI_LISTEN_PORT
  • Removed LaunchAgent from indri, cleared Tailscale serve entry

Previous (indri era)

  • Initial setup with devpi on indri via mcquack LaunchAgent
  • Connected via Tailscale at pypi.tail8d86e.ts.net
  • Created eblume/dev index for private packages
  • Metrics collection via textfile exporter