From 13fadc08900a574058a4746eb27fb7da71766d6a Mon Sep 17 00:00:00 2001 From: MA1503 <122182117+MA1503@users.noreply.github.com> Date: Fri, 24 Jul 2026 23:22:31 +0200 Subject: [PATCH 1/2] fix(config): let OS env win over .env so Docker config injection works MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit config.py called load_dotenv(override=True), which makes a .env file take precedence over real OS environment variables. That inverts the standard convention and breaks the Docker deployment model, where docker-compose feeds configuration into the container through the environment (env_file). The value that matters most here is NEO4J_URI: inside the container it must resolve to the compose service (bolt://neo4j:7687), not the localhost value that is only correct for native dev with a port-mapped Neo4j. Any .env that reaches the container (baked in, bind-mounted, or shipped by a fork) would silently override the injected value with override=True, and the backend would dial localhost:7687 inside the container — nothing there — and crash graph build with Connection refused. Fix: both load_dotenv() calls use override=False, so OS env wins. Native dev is unchanged — those vars aren't in the OS env there, so the .env values still load. Co-Authored-By: Claude Fable 5 --- backend/app/config.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/backend/app/config.py b/backend/app/config.py index de706ca4..cdd7fe40 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -8,13 +8,22 @@ # Load .env file from project root # Path: MiroFish/.env (relative to backend/app/config.py) +# +# override=False is deliberate: real OS environment variables must win over the +# .env file. The Docker deployment feeds configuration into the container through +# the environment — docker-compose injects the vars from `.env` via `env_file:` +# (and NEO4J_URI must point at the compose service, e.g. bolt://neo4j:7687, not +# the localhost value that is only correct for native dev). With override=True a +# stray/baked .env would silently clobber that injection, so the backend would +# dial localhost inside the container and never reach the neo4j service. For +# native dev nothing changes: those vars aren't in the OS env, so .env still loads. project_root_env = os.path.join(os.path.dirname(__file__), '../../.env') if os.path.exists(project_root_env): - load_dotenv(project_root_env, override=True) + load_dotenv(project_root_env, override=False) else: # If no .env in root, try to load environment variables (for production) - load_dotenv(override=True) + load_dotenv(override=False) class Config: From 9c06e90523c28934c3f367ecfaa002c5c885f21a Mon Sep 17 00:00:00 2001 From: MA1503 <122182117+MA1503@users.noreply.github.com> Date: Fri, 24 Jul 2026 23:22:47 +0200 Subject: [PATCH 2/2] fix(docker): pre-seed tiktoken BPE cache at build time for offline runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CAMEL/OASIS token counting imports tiktoken, which downloads o200k_base/cl100k_base from openaipublic.blob.core.windows.net on first use — a hidden runtime cloud dependency. In the container the simulation subprocess crashes with NameResolutionError whenever DNS is unavailable, which defeats the point of an offline-first stack. Native runs never hit this because the host has internet and a warm cache. Bake both encodings into the image via TIKTOKEN_CACHE_DIR and a build-time download, so simulation runtime needs zero external hosts. Co-Authored-By: Claude Fable 5 --- Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Dockerfile b/Dockerfile index df28213e..72931572 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,6 +20,14 @@ RUN npm ci \ && npm ci --prefix frontend \ && cd backend && uv sync +# Pre-seed the tiktoken BPE encodings at build time. CAMEL/OASIS token counting +# imports tiktoken, which otherwise downloads o200k_base/cl100k_base from +# openaipublic.blob.core.windows.net on first use — a runtime cloud dependency +# that crashes the simulation subprocess in offline or DNS-restricted +# environments. Baking them in keeps simulation runtime fully offline. +ENV TIKTOKEN_CACHE_DIR=/app/tiktoken_cache +RUN cd backend && uv run python -c "import tiktoken; tiktoken.get_encoding('o200k_base'); tiktoken.get_encoding('cl100k_base')" + # 复制项目源码 COPY . .