Install the image's dependencies from uv.lock, so it can run its own jobs (#173) #174

Merged
claude-bot merged 1 commit from fix/173-image-deps into main 2026-09-26 11:06:18 +00:00
Collaborator

Closes #173. This is the main half of the fix. The same commit is already tagged as v1.1.2 on release/1.1.x (cut from v1.1.1), because main carries unreleased v1.2.0 work.

The bug

The Dockerfile installed from a hand-kept backend/requirements.txt that lacked prometheus-client, defusedxml and zeroconf. log_run (every scheduler job) and _try_push (every push_with_fallback) import app.services.metrics. So in the published 1.1.0 and 1.1.1 images, the on, dim and off jobs fail before they do anything, while the container starts and passes its health check.

Verified inside a running container of each image:

published 1.1.1 this fix
log_run("probe", "success") ModuleNotFoundError: prometheus_client OK
import every app.* module backup_targets (defusedxml) and metrics (prometheus_client) fail all import
pytest / respx / pip / uv in the runtime image pytest and respx present none

Fix

  • The build installs from uv.lock: uv export --frozen --no-dev --no-emit-project with hashes, then pip install --require-hashes. uv is used only in the build stage. requirements.txt is deleted, so there's no second list.
  • audit.yml pip-audits the same export. It had been auditing the stale file too.
  • The new CI step "Import every app module inside the image" runs right after the build. It fails on the 1.1.1 image and passes on this one.
  • CHANGELOG: a [1.1.2] section below [Unreleased], and the link refs.

Known limit: zeroconf is imported lazily inside a function, so a module-import sweep can't catch its absence. It's now installed from the lock anyway.

🤖 Generated with Claude Code

Closes #173. This is the `main` half of the fix. The same commit is already tagged as **v1.1.2** on `release/1.1.x` (cut from `v1.1.1`), because `main` carries unreleased v1.2.0 work. ## The bug The Dockerfile installed from a hand-kept `backend/requirements.txt` that lacked `prometheus-client`, `defusedxml` and `zeroconf`. `log_run` (every scheduler job) and `_try_push` (every `push_with_fallback`) import `app.services.metrics`. So in the published 1.1.0 and 1.1.1 images, the on, dim and off jobs fail before they do anything, while the container starts and passes its health check. Verified inside a running container of each image: | | published 1.1.1 | this fix | |---|---|---| | `log_run("probe", "success")` | `ModuleNotFoundError: prometheus_client` | OK | | import every `app.*` module | `backup_targets` (defusedxml) and `metrics` (prometheus_client) fail | all import | | pytest / respx / pip / uv in the runtime image | pytest and respx present | none | ## Fix - **The build installs from `uv.lock`:** `uv export --frozen --no-dev --no-emit-project` with hashes, then `pip install --require-hashes`. uv is used only in the build stage. `requirements.txt` is deleted, so there's no second list. - **`audit.yml`** pip-audits the same export. It had been auditing the stale file too. - **The new CI step "Import every app module inside the image"** runs right after the build. It fails on the 1.1.1 image and passes on this one. - **CHANGELOG:** a `[1.1.2]` section below `[Unreleased]`, and the link refs. **Known limit:** `zeroconf` is imported lazily inside a function, so a module-import sweep can't catch its absence. It's now installed from the lock anyway. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Install the image's dependencies from uv.lock, so it can run its own jobs (#173)
Some checks failed
CI / Python lint & type-check (pull_request) Successful in 1m6s
CI / Dockerfile lint (pull_request) Successful in 7s
CI / Pre-commit hooks (pull_request) Successful in 2m21s
CI / Alembic migration check (pull_request) Successful in 1m33s
CI / Frontend lint, test & build (pull_request) Successful in 1m42s
CI / Python tests (pull_request) Successful in 5m43s
CI / Docker build, health smoke & E2E (pull_request) Failing after 5m33s
a140ad358e
The hand-kept backend/requirements.txt had drifted from pyproject.toml:
prometheus-client, defusedxml and zeroconf were never added, so the 1.1.0
and 1.1.1 images could not import app.services.metrics, which log_run
(every scheduler job) and _try_push (every push) import. The build now
exports the locked runtime set from uv.lock with hashes, requirements.txt
is deleted, the weekly audit audits the same export, and CI imports every
app module inside the built image.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
rbrooks force-pushed fix/173-image-deps from a140ad358e
Some checks failed
CI / Python lint & type-check (pull_request) Successful in 1m6s
CI / Dockerfile lint (pull_request) Successful in 7s
CI / Pre-commit hooks (pull_request) Successful in 2m21s
CI / Alembic migration check (pull_request) Successful in 1m33s
CI / Frontend lint, test & build (pull_request) Successful in 1m42s
CI / Python tests (pull_request) Successful in 5m43s
CI / Docker build, health smoke & E2E (pull_request) Failing after 5m33s
to 6767f64373
All checks were successful
CI / Dockerfile lint (pull_request) Successful in 13s
CI / Alembic migration check (pull_request) Successful in 35s
CI / Python lint & type-check (pull_request) Successful in 1m11s
CI / Pre-commit hooks (pull_request) Successful in 1m34s
CI / Frontend lint, test & build (pull_request) Successful in 1m33s
CI / Python tests (pull_request) Successful in 5m34s
CI / Docker build, health smoke & E2E (pull_request) Successful in 4m10s
2026-09-26 10:55:36 +00:00
Compare
claude-bot deleted branch fix/173-image-deps 2026-09-26 11:06:19 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Iris-WLED!174
No description provided.