Conversation
MLflow defaults its tracking store to the relative URI sqlite:///mlflow.db, which it resolves against the process working directory. In the worker container that directory is /app on a read-only filesystem, so creating a run fails with "unable to open database file" after ~100 seconds of retries. This hits every model whose MLproject declares python_env, since those route to MlFlowTrainPredictRunner and therefore to mlflow.projects.run. Fall back to a sqlite file under CHAP_RUNS_DIR when MLFLOW_TRACKING_URI is not set. A tracking URI configured by the deployment still wins.
knutdrand
marked this pull request as draft
August 17, 2026 12:33
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Model runs in the worker container fail with:
MLflow defaults its tracking store to the relative URI
sqlite:///mlflow.db(mlflow/store/tracking/__init__.py,DEFAULT_TRACKING_URI) and resolves it against the process working directory. The worker hasWORKDIR /appand runs withread_only: true, so the file cannot be created.This is not a dependency drift. The sqlite default landed in mlflow-skinny 3.7.0 and is present in every version our range allows, including the 3.11.1 the lockfile pins. Downgrading does not help either: 3.6.0 defaults to
./mlruns, which resolves to the same read-only/app. The variable is the working directory, not the version.The failure is not cosmetic.
create_sqlalchemy_engine_with_retryretries 10 times with exponential backoff, roughly 100 seconds, and then raises.Only models whose MLproject declares
python_envare affected.helper_functions.pymaps those toMlFlowTrainPredictRunner, which callsmlflow.projects.runand therefore creates a tracking run. Models usingdocker_env,uv_env,renv_env, orconda_envgo throughCommandLineTrainPredictRunnerand never touch MLflow tracking. Reproduced with https://github.com/chap-models/minimal_template_example.Fix
When
MLFLOW_TRACKING_URIis unset, default the tracking store to a sqlite file underCHAP_RUNS_DIR, which is writable in every deployment (/data/runsin the worker, alreadychown chap:chapinDockerfile.worker). A tracking URI configured by the deployment is left untouched.This lives in code rather than in
compose.ymlso it also coverscompose.ghcr.ymland the skaffold deployment. MLflow's own_make_parent_dirs_if_sqlitecreates the parent directory, so the helper has no filesystem side effects, andset_tracking_urimirrors the value into the environment so the project subprocess inherits it.Tests
Two tests in
tests/runners/test_runners.py: the fallback lands underCHAP_RUNS_DIR, and a deployment-configured URI wins. Added amlflow_tracking_uri_resetfixture sinceset_tracking_urimutates process-global state, and applied it to the two existing mlflow runner tests so they no longer leak into the rest of the session.tests/runners/test_runners.py: 24 passed, 1 skipped.Full
make test: 798 passed, 1 failed. The failure istest_db_endpoints.py::test_make_prediction_with_data_source_nonexistent_id(NameError: name 'MakePredictionWithDataSourceRequest' is not defined), which fails identically onfeat/hpo-rest-apiwith this branch's changes stashed.make lintreports 2 mypy errors in the same file, also pre-existing on the base.Not covered
_get_sqlalchemy_storefalls back toDEFAULT_LOCAL_FILE_AND_ARTIFACT_PATHfor the artifact root, so artifacts still target/app/mlruns.minimal_template_examplelogs no artifacts so this is not hit today, but a model that does will fail the same way. The only override is the private_MLFLOW_SERVER_ARTIFACT_ROOT; the real fix is moving the worker'sworking_diroff/app, which has a wider blast radius and is left for a separate change.