Skip to content

Instantly share code, notes, and snippets.

@hoghweed
Last active June 24, 2026 09:54
Show Gist options
  • Select an option

  • Save hoghweed/6393502f87f8c64e5afc19b8c983af0c to your computer and use it in GitHub Desktop.

Select an option

Save hoghweed/6393502f87f8c64e5afc19b8c983af0c to your computer and use it in GitHub Desktop.
headroom-ai local patches: fix persistent-docker startup (duplicate ENTRYPOINT) + container HF cache permission spam. Idempotent, re-apply after pipx upgrade.
#!/usr/bin/env bash
# Re-apply local headroom-ai patches and restart the persistent deployment.
# Run after every `pipx upgrade headroom-ai`. Idempotent.
set -euo pipefail
VENV_PY="${HEADROOM_VENV_PY:-$HOME/.local/pipx/venvs/headroom-ai/bin/python}"
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROFILE="${HEADROOM_PROFILE:-default}"
if [[ ! -x "$VENV_PY" ]]; then
echo "error: headroom venv python not found at $VENV_PY" >&2
echo "set HEADROOM_VENV_PY=/path/to/venv/bin/python and retry" >&2
exit 1
fi
echo "==> patching package"
"$VENV_PY" "$HERE/patch_headroom.py"
# Restart the running deployment so the new docker args/env take effect.
if command -v headroom >/dev/null 2>&1; then
if headroom install status --profile "$PROFILE" >/dev/null 2>&1; then
echo "==> restarting deployment '$PROFILE'"
headroom install restart --profile "$PROFILE" 2>/dev/null \
|| headroom install apply --profile "$PROFILE" --preset persistent-docker --providers auto
else
echo "==> no deployment '$PROFILE' installed; skipping restart"
fi
fi
echo "==> done"

headroom-ai local patches

Reusable, idempotent patches for the pipx-installed headroom-ai package. pipx upgrade headroom-ai overwrites package files, so re-run after upgrades. Safe to run any number of times — already-applied patches are a no-op.

Quick start

# clone this gist anywhere
git clone https://gist.github.com/6393502f87f8c64e5afc19b8c983af0c.git headroom-patches
cd headroom-patches
chmod +x apply.sh patch_headroom.py
./apply.sh

apply.sh patches the package, then restarts the default persistent deployment.

Override defaults via env:

  • HEADROOM_VENV_PY — path to the headroom venv python (default ~/.local/pipx/venvs/headroom-ai/bin/python)
  • HEADROOM_PROFILE — deployment profile to restart (default default)

Patch only, no restart:

~/.local/pipx/venvs/headroom-ai/bin/python patch_headroom.py

Exit codes: 0 applied/no-op, 2 an anchor was not found (upstream source changed — re-derive the patch before trusting it).

What it patches — headroom/install/runtime.py, build_runtime_command

  1. docker-entrypoint-dupe — the code appends headroom proxy to the container args, but the image ENTRYPOINT is already ["headroom","proxy"]. The duplicate makes click fail with Got unexpected extra arguments (headroom proxy), the container crashes on start, and headroom install apply --preset persistent-docker never becomes ready (Deployment 'default' did not become ready after start.). Fix: pass only the proxy flags.

  2. cache-perms — the container HOME (/tmp/headroom-home) is the docker workdir, created root-owned and not writable by the --user uid, so huggingface_hub/onnx spam [Errno 13] Permission denied: .../.cache on every request. Fix: redirect XDG_CACHE_HOME / HF_HOME / HUGGINGFACE_HUB_CACHE into the bind-mounted, user-writable .headroom dir (also persists the cache across restarts).

Files

  • patch_headroom.py — self-locating, idempotent patcher (the source of truth)
  • apply.sh — wrapper: patch + restart deployment
  • runtime.py.prepatch (created next to the package file) — pristine snapshot taken on first apply after each upgrade

Notes

Both are bugs in headroom-ai itself; these patches are a stopgap until they're fixed upstream. Tested against the persistent-docker preset. The patcher only edits source it can match exactly and recompiles after, so a changed upstream file fails loudly (exit 2) rather than silently corrupting the install.

#!/usr/bin/env python3
"""Idempotent local patches for the installed `headroom-ai` package.
Re-apply after every `pipx upgrade headroom-ai` (upgrades overwrite the
package files). Safe to run repeatedly — each patch detects whether it is
already applied and is a no-op if so.
Run with the headroom venv's python so it patches the right install:
~/.local/pipx/venvs/headroom-ai/bin/python patch_headroom.py
(the apply.sh wrapper does this for you, plus pyc-clear + restart.)
Patches:
1. docker-entrypoint-dupe — install/runtime.py build_runtime_command appends
`headroom proxy` to the container args, but the image ENTRYPOINT is already
["headroom","proxy"]. The duplicate makes click fail with
"Got unexpected extra arguments (headroom proxy)" and the container crashes
on start, so `headroom install apply --preset persistent-docker` never
becomes ready.
2. cache-perms — the container's HOME (/tmp/headroom-home) is the docker
workdir, created root-owned and not writable by the --user uid, so
huggingface_hub/onnx spam "[Errno 13] Permission denied: .../.cache" on
every request. Redirect the framework caches into the bind-mounted,
user-writable .headroom dir.
"""
from __future__ import annotations
import importlib
import py_compile
import sys
from pathlib import Path
def _runtime_path() -> Path:
mod = importlib.import_module("headroom.install.runtime")
if not mod.__file__:
raise SystemExit("could not locate headroom.install.runtime")
return Path(mod.__file__)
# --- Patch 1: drop the duplicate "headroom","proxy" container args -----------
P1_OLD = (
' manifest.image,\n'
' "headroom",\n'
' "proxy",\n'
' "--host",\n'
)
P1_NEW = (
' manifest.image,\n'
' "--host",\n'
)
def _apply_p1(text: str) -> tuple[str, str]:
if P1_OLD in text:
return text.replace(P1_OLD, P1_NEW, 1), "applied"
if '"headroom",\n "proxy",' not in text and "manifest.image," in text:
return text, "already-applied"
return text, "anchor-not-found"
# --- Patch 2: redirect framework caches to the writable .headroom mount ------
P2_ANCHOR = (
' "--env",\n'
' f"HEADROOM_CONFIG_DIR={container_home}/.headroom/config",\n'
' "--volume",\n'
)
P2_NEW = (
' "--env",\n'
' f"HEADROOM_CONFIG_DIR={container_home}/.headroom/config",\n'
' # HOME (=container_home) is the docker-created workdir, owned by root and\n'
' # not writable by the --user uid. Redirect framework caches into the\n'
' # bind-mounted, user-writable .headroom dir so huggingface_hub/onnx stop\n'
' # raising "[Errno 13] Permission denied: .../.cache" on every request.\n'
' "--env",\n'
' f"XDG_CACHE_HOME={container_home}/.headroom/cache",\n'
' "--env",\n'
' f"HF_HOME={container_home}/.headroom/cache/huggingface",\n'
' "--env",\n'
' f"HUGGINGFACE_HUB_CACHE={container_home}/.headroom/cache/huggingface/hub",\n'
' "--volume",\n'
)
def _apply_p2(text: str) -> tuple[str, str]:
if "XDG_CACHE_HOME={container_home}" in text:
return text, "already-applied"
if P2_ANCHOR in text:
return text.replace(P2_ANCHOR, P2_NEW, 1), "applied"
return text, "anchor-not-found"
def main() -> int:
path = _runtime_path()
original = path.read_text(encoding="utf-8")
text = original
results = {}
text, results["docker-entrypoint-dupe"] = _apply_p1(text)
text, results["cache-perms"] = _apply_p2(text)
failed = [name for name, status in results.items() if status == "anchor-not-found"]
changed = text != original
if changed:
backup = path.with_suffix(path.suffix + ".prepatch")
if not backup.exists():
backup.write_text(original, encoding="utf-8")
path.write_text(text, encoding="utf-8")
# Fail fast on a broken edit rather than leaving an unimportable module.
py_compile.compile(str(path), doraise=True)
# Drop stale bytecode so the next run uses the patched source.
for pyc in (path.parent / "__pycache__").glob(f"{path.stem}.*.pyc"):
pyc.unlink()
print(f"target: {path}")
for name, status in results.items():
print(f" {name}: {status}")
print("changed: yes" if changed else "changed: no (nothing to do)")
if failed:
print(
"\nWARNING: anchors not found for: "
+ ", ".join(failed)
+ "\nThe upstream code likely changed. Re-derive the patch against the "
"new source before trusting it.",
file=sys.stderr,
)
return 2
return 0
if __name__ == "__main__":
raise SystemExit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment