fix(docker): keep config mounts stable across host saves (#3954)
Some checks are pending
Backend Blocking IO / backend-blocking-io (push) Waiting to run
Unit Tests / backend-unit-tests (push) Waiting to run
E2E Tests / e2e-tests (push) Waiting to run
Frontend Unit Tests / frontend-unit-tests (push) Waiting to run
Lint Check / lint-backend (push) Waiting to run
Lint Check / lint-frontend (push) Waiting to run
Replay E2E (front-back contract) / Layer 1 — backend golden (no API key) (push) Waiting to run
Replay E2E (front-back contract) / Layer 2 — full-stack render (no API key) (push) Waiting to run

* fix(docker): keep mutable config mounts stable

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Huixin615 2026-07-06 08:00:49 +08:00 committed by GitHub
parent 0664ea2243
commit eb5eb9c574
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 21 additions and 2 deletions

View file

@ -283,6 +283,11 @@ Config values starting with `$` are resolved as environment variables (e.g., `$O
MCP servers and skills are configured together in `extensions_config.json` in project root:
Docker development mounts the project directory at `/app/project` and points
`DEER_FLOW_CONFIG_PATH` / `DEER_FLOW_EXTENSIONS_CONFIG_PATH` into that directory.
Keep mutable config files behind a directory bind mount: single-file bind mounts
can become stale or inaccessible when a host editor replaces a file on save.
Configuration priority:
1. Explicit `config_path` argument
2. `DEER_FLOW_EXTENSIONS_CONFIG_PATH` environment variable

View file

@ -43,6 +43,16 @@ def test_service_launchers_always_use_gateway_runtime():
assert "LANGGRAPH_REWRITE" not in content, path
def test_docker_dev_mounts_mutable_configs_through_project_directory():
compose = _read("docker/docker-compose-dev.yaml")
assert re.search(r"^\s*-\s*\.\./:/app/project(?:\:\S+)?\s*$", compose, re.M)
assert not re.search(r"^\s*-\s*[^\n#]*config\.yaml\s*:\s*[^\n#]*$", compose, re.M)
assert not re.search(r"^\s*-\s*[^\n#]*extensions_config\.json\s*:\s*[^\n#]*$", compose, re.M)
assert "DEER_FLOW_CONFIG_PATH=/app/project/config.yaml" in compose
assert "DEER_FLOW_EXTENSIONS_CONFIG_PATH=/app/project/extensions_config.json" in compose
def test_local_dev_gateway_reload_excludes_runtime_state_with_absolute_dirs():
serve_sh = _read("scripts/serve.sh")

View file

@ -155,8 +155,10 @@ services:
# Preserve the .venv built during Docker image build — mounting the full backend/
# directory above would otherwise shadow it with the (empty) host directory.
- gateway-venv:/app/backend/.venv
- ../config.yaml:/app/config.yaml
- ../extensions_config.json:/app/extensions_config.json
# Mount the project directory instead of its mutable config files individually.
# Host editors commonly replace files on save; a directory bind keeps those
# replacements visible inside Docker Desktop/WSL containers.
- ../:/app/project
- ../skills:/app/skills
- ../logs:/app/logs
# Use a Docker-managed uv cache volume instead of a host bind mount.
@ -178,6 +180,8 @@ services:
- CI=true
- DEER_FLOW_PROJECT_ROOT=/app
- DEER_FLOW_HOME=/app/backend/.deer-flow
- DEER_FLOW_CONFIG_PATH=/app/project/config.yaml
- DEER_FLOW_EXTENSIONS_CONFIG_PATH=/app/project/extensions_config.json
- DEER_FLOW_STREAM_BRIDGE_REDIS_URL=${DEER_FLOW_STREAM_BRIDGE_REDIS_URL:-redis://redis:6379/0}
- DEER_FLOW_CHANNELS_LANGGRAPH_URL=${DEER_FLOW_CHANNELS_LANGGRAPH_URL:-http://gateway:8001/api}
- DEER_FLOW_CHANNELS_GATEWAY_URL=${DEER_FLOW_CHANNELS_GATEWAY_URL:-http://gateway:8001}