feat(server): support MEM0_CONFIG_PATH env var for K8s ConfigMap-driven config#5338
Open
shivamtyagi18 wants to merge 1 commit into
Open
feat(server): support MEM0_CONFIG_PATH env var for K8s ConfigMap-driven config#5338shivamtyagi18 wants to merge 1 commit into
shivamtyagi18 wants to merge 1 commit into
Conversation
…en config Adds env-var indirection to the server's config-loading path so the deployment can mount a YAML config file from a Kubernetes ConfigMap (or any other declarative source) without baking config into the image. Behavior: - If MEM0_CONFIG_PATH is set, the YAML file at that path is parsed and merged into the running config via the existing _merge_config helper before DB overrides apply. - If MEM0_CONFIG_PATH is unset, behavior is unchanged from current main — pure additive. Precedence (low → high): DEFAULT_CONFIG < MEM0_CONFIG_PATH < DB. Motivation: deploying mem0 to Kubernetes today requires either a runtime POST /configure call on every pod restart, or baking the config into a custom image build. Both are operationally fragile. The standard 12-factor pattern is a ConfigMap mounted at a stable path with the location passed via env var — this PR enables that. Fail-soft on errors (missing file, invalid YAML, non-mapping top-level) — matches the style of the existing _load_overrides function. Operator misconfiguration produces clear ERROR logs but the server still boots on defaults rather than crash-looping. Same trade-off the surrounding code already makes. Files: - server/server_state.py — new _load_yaml_config_path() function + call site inside initialize_state(); errors logged with exc_info=True - server/requirements.txt — adds pyyaml>=6.0,<7.0 (only imported lazily inside _load_yaml_config_path; no impact when env var unset) - server/tests/__init__.py — new empty test package - server/tests/test_mem0_config_path.py — 8 tests covering env-set and env-unset paths, 3 error-fallback paths, and 2 initialize_state integration tests (uses monkeypatched mem0.Memory stub for fast execution, ~0.02s for the full file) Tests pass with the existing pytest setup. No changes to the public HTTP API.
Author
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.
Summary
Closes #5339 (first half —
MEM0_CONFIG_PATH; Docker Hub publishing half tracked separately on the issue)Adds env-var indirection to the mem0 server's config-loading path so a deployment can mount a YAML config file from a Kubernetes ConfigMap (or any other declarative source) without baking config into the image.
_load_yaml_config_path()inserver/server_state.py— readsMEM0_CONFIG_PATHenv var at startup, parses the referenced YAML, merges it into the running config via the existing_merge_confighelper.initialize_state()before DB overrides apply.pyyaml>=6.0,<7.0added toserver/requirements.txt(lazy-imported inside the function — no impact when the env var is unset).server/tests/test_mem0_config_path.pycovering env-set and env-unset paths, 3 error-fallback paths, and 2initialize_stateintegration tests. All pass in ~0.02s.Motivation
Deploying mem0 to Kubernetes today requires one of:
POST /configureon every pod restart — fragile, racy, and requires custom orchestration outside the K8s declarative model.The standard 12-factor pattern is a ConfigMap mounted at a stable path, with the location passed via an env var. This PR enables that:
After this PR, the operator edits the ConfigMap → kubectl rolls the pod → server picks up the new config at startup. No image rebuild, no runtime POST.
Design notes
DEFAULT_CONFIG<MEM0_CONFIG_PATH< DB overrides. Matches the existing layered-overrides model.MEM0_CONFIG_PATHis unset. Pure additive — no regressions for existing users._load_overridesfunction: operator misconfiguration produces clear ERROR logs (withexc_info=Truefor parse failures) but the server still boots on defaults rather than crash-looping. Same trade-off the surrounding code already makes; I considered failing fast to prevent silent-wrong-config but chose consistency with the file's existing style. Happy to switch to fail-fast if maintainers prefer.MEM0_CONFIG_PATHis actually set. If pyyaml is missing the function logs an actionable ERROR and falls back to defaults rather than crashing imports.Test coverage
The new test file covers:
{}(no-op){}{}{}initialize_state()called with no env var → identical behavior to current maininitialize_state()called with env var → loaded config is mergedUses monkeypatched
mem0.Memoryto keep test runtime fast (~0.02s for the full file).Out of scope (intentional)
POST /configureremains the runtime-config path;MEM0_CONFIG_PATHis the startup-config path.server/Dockerfile,docker-compose.yml, or the existingcd.ymlPyPI publish workflow.MEM0_CONFIG_PATH.Test plan
main(python3 -m pytest server/tests/test_mem0_config_path.py -q)pyyamlimport is lazy and only triggers when env var is setCompanion issue
I've also filed an issue describing the broader K8s deployment gaps I hit (this PR addresses the
MEM0_CONFIG_PATHhalf; the other half is the Docker Hub image publishing cadence). Happy to discuss approach changes there before further work.Thanks for mem0 — the cross-thread recall semantics are exactly what we needed and the server is rock-solid. This patch came out of running mem0 in production K8s; the only friction point was config indirection. Hope this is useful.