This repo's Dockerfile has always pulled a pre-built upstream image
(FROM .../ghcr-proxy/open-webui/open-terminal:latest) and only added
wrapper tooling on top. It never built or installed this repo's own
vendored open_terminal/ package -- every fix this CHANGELOG has
described as applied to open_terminal/main.py was real, tested,
merged code that the running container never actually ran. See
homelab#822 for the full incident writeup.
Root cause found while investigating why homelab#720's security fix
(process-log retention) wasn't live despite being merged days ago.
Auditing the vendored package's full history surfaced three more real,
undeployed fixes beyond that one, all now submitted upstream:
- open-webui/open-terminal#148 -- configurable uvicorn keep-alive
timeout (intermittent ConnectionResetError)
- open-webui/open-terminal#149 -- process-log retention security fix
- open-webui/open-terminal#150 -- two-tier process-result expiry
(a slow caller could lose a finished command's result forever)
- open-webui/open-terminal#151 -- insert_after/append_to_section/
append endpoints + a defensive replace_file_content check
Plus one homelab-specific fix NOT appropriate for upstream (ties into
our own GH App token-file convention, not something upstream has any
hook for): refresh_github_token_env(), re-reads the current token
from disk before every subprocess spawn, closing a gap BASH_ENV-based
shell-profile sourcing doesn't cover (plain-shell and PTY spawn paths
never source /etc/profile.d).
## What changed
- Dockerfile: stage 1 now builds open_terminal from
dvystrcil/open-terminal-app-fork (a real fork carrying all 5 fixes
above) via git clone + pip install ., mirroring upstream's own
Dockerfile exactly, instead of pulling the pre-built upstream image.
TEMPORARY -- revert to a plain upstream FROM once all four PRs merge
and a release picks them up.
- docker.yml: resolves the fork's current commit SHA via `git
ls-remote` and passes it as a build-arg on every run. Without this,
Docker's build cache (keyed on RUN command text, not on what `git
clone --branch main` actually fetches) would silently keep shipping
whatever fork commit was cloned the FIRST time this layer built,
even after new fixes land on the fork -- caught this empirically:
an initial local build without the explicit build-arg produced a
stale image missing later fixes despite a fresh fork push.
- Removed the vendored open_terminal/ package and its tests -- dead
weight now that the real fixes live in a fork with a real upstream
relationship. Kept tests/test_actor_env.py (tests
helpers/bible_bridge.py, which *is* deployed) and tests/__init__.py.
Removed pyproject.toml, dev.sh, .python-version (all specific to
developing the now-removed vendored package).
- README: documents the new build shape and the incident.
## Testing
Built the actual image locally (multi-stage, full apt/pip install,
~2 min), ran it, and verified all 5 fixes are present in the running
container (direct imports of the sweep function, keep-alive/expiry
env values, refresh_github_token_env, and the three new endpoint
handlers) plus the health endpoint and all wrapper tools (kubectl,
gh, yq, argocd, act) and the entrypoint's token-refresh profile.
Confirmed the FORK_SHA cache-bust actually works: an explicit
--build-arg forces a genuine re-clone (visible in build output, not
a CACHED layer) rather than silently reusing a stale one.
tests/test_actor_env.py still passes standalone (7/7) against the
real helpers/bible_bridge.py, unaffected by the removed package.
User description
The core problem (homelab#822)
This repo's Dockerfile has always pulled a pre-built upstream image and only added wrapper tooling on top. It never built or installed this repo's own vendored
open_terminal/package -- every fix this CHANGELOG has described as applied toopen_terminal/main.pywas real, tested, merged code that the running container never actually ran.Root-caused while investigating why homelab#720's security fix (process-log retention) wasn't live despite being merged days ago. Auditing the vendored package's full history surfaced three more real, undeployed fixes beyond that one -- all now submitted upstream:
ConnectionResetError)insert_after/append_to_section/appendendpoints + a defensivereplace_file_contentcheckPlus one homelab-specific fix, ported to the fork but not submitted upstream (it's specific to our own GH App token-file convention):
refresh_github_token_env()re-reads the current token from disk before every subprocess spawn, closing a gapBASH_ENV-based shell-profile sourcing doesn't cover.What changed
open_terminalfromdvystrcil/open-terminal-app-fork(carries all 5 fixes above) viagit clone+pip install ., mirroring upstream's own Dockerfile exactly, instead of pulling the pre-built upstream image. Temporary -- revert to a plain upstreamFROMonce all four PRs merge and a release picks them up.git ls-remoteand passes it as a build-arg on every run. Without this, Docker's build cache (keyed on RUN command text, not on whatgit clone --branch mainactually fetches) silently keeps shipping whatever fork commit was cloned the first time -- caught this empirically: a local build without the explicit build-arg produced a stale image missing later fixes despite a fresh fork push.open_terminal/package and its tests -- dead weight now that the real fixes live in a fork with a real upstream relationship. Kepttests/test_actor_env.py(testshelpers/bible_bridge.py, which is deployed) andtests/__init__.py. Removedpyproject.toml,dev.sh,.python-version(all specific to developing the now-removed vendored package).Test plan
refresh_github_token_env, the three new endpoint handlers), plus/healthand all wrapper tools (kubectl, gh, yq, argocd, act) and the entrypoint's token-refresh profile.FORK_SHAcache-bust actually works: an explicit--build-argforces a genuine re-clone (visible in build output, not aCACHEDlayer) rather than silently reusing a stale one -- this is exactly the class of bug this whole PR exists to fix, so I wanted a real receipt that the fix works, not just that it looks right.tests/test_actor_env.pystill passes standalone (7/7) against the realhelpers/bible_bridge.py.Ref homelab#822 -- NOT closing it. This fixes the diagnosis and gets the real fixes deployed via the fork, but the issue's underlying "vendored source disconnected from the build" risk only fully resolves once all four upstream PRs merge and this Dockerfile reverts to a plain upstream
FROM.PR Type
Bug fix, CI/CD Update, Documentation, Build Process Refactoring
Description
This PR addresses a critical deployment gap where previously documented fixes for
open_terminalwere never actually built into the container image. The Dockerfile is refactored to use a multi-stage build that clones and installs from a temporary fork (dvystrcil/open-terminal-app-fork) carrying the necessary upstream PRs. The CI workflow is updated to resolve the fork's current HEAD SHA and pass it as a build argument to prevent Docker layer caching issues withgit clone --branch main. Documentation and changelog are updated to reflect the removal of the dead vendored package and the temporary nature of this change.Diagram Walkthrough
File Walkthrough
1 files
Refactor to multi-stage build from temporary fork; add devops tools &Python deps; set up user & metadata1 files
Add step to resolve fork HEAD SHA and pass as build-arg to bust Dockercache2 files
Document undeployed fixes, new fork-based build process, and removalof vendored packageUpdate repository layout and clarify that the repo no longer vendorsopen_terminalsource25 files