fix(docker): make the Docker deployment actually work offline - #65
Open
MA1503 wants to merge 2 commits into
Open
fix(docker): make the Docker deployment actually work offline#65MA1503 wants to merge 2 commits into
MA1503 wants to merge 2 commits into
Conversation
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 <noreply@anthropic.com>
…ntime 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 <noreply@anthropic.com>
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.
Why
MiroFish-Offline sells itself as a fully local, offline-first stack — but two
runtime cloud/config dependencies leak through the Docker path and break a clean
docker compose up. Neither shows up in native dev (the host has internet, awarm cache, and localhost-mapped services), so they stay hidden until you run
the thing the way the README tells people to run it: in containers.
This PR fixes both. They are independent one-liners, one commit each.
1. OS env must win over
.env(config injection)backend/app/config.pyloaded the.envfile withload_dotenv(override=True),which makes the
.envfile take precedence over real OS environment variables.That inverts the usual convention and, more importantly, contradicts this
project's own Docker deployment model:
docker-compose.ymlfeeds configurationinto the container through the environment (
env_file: - .env), and the keyvalue there is
NEO4J_URI— inside the container it has to resolve to thecompose service (
bolt://neo4j:7687), not thelocalhost:7687value that isonly correct for native dev with a port-mapped Neo4j.
With
override=True, any.envthat reaches the container — baked into theimage, bind-mounted, or shipped by a downstream fork — silently clobbers the
injected value, and the backend dials
localhost:7687inside the container,where nothing is listening. Graph build then crashes with
Connection refused.Fix: both
load_dotenv()calls useoverride=False. OS env wins. Native dev isunchanged, because those variables aren't in the OS environment there, so the
.envvalues still load as before.2. Pre-seed the tiktoken BPE cache at build time (offline runtime)
CAMEL/OASIS counts tokens with
tiktoken, which downloads its BPE encodings(
o200k_base,cl100k_base) fromopenaipublic.blob.core.windows.neton firstuse — a hidden runtime cloud dependency. In the container the simulation
subprocess crashes with
NameResolutionErrorthe moment DNS is unavailable,which is exactly the environment an "offline" stack is supposed to survive.
Native runs never hit this because the host has internet and a warm cache.
Fix: set
TIKTOKEN_CACHE_DIRand download both encodings during the imagebuild, so simulation runtime needs zero external hosts.
What this PR does not change
.dockerignorealready exists inmainand is comprehensive — it alreadyexcludes
.env,backend/.venv,node_modules,.git, andbackend/uploads, so the image doesn't drag in the host venv (which would makeuvre-sync from PyPI on every container start) and doesn't bake secrets. Nochange needed.
.envinto the container is already handled:docker-compose.ymlpassesit via
env_file: - .env, so config still reaches the container even though.envis (correctly) kept out of the image.Testing notes
backend/app/config.pystill parses (ast.parse), and the change is a puredefault flip on
load_dotenv.ENV+RUNinserted afteruv sync(so
tiktokenis already installed) and beforeCOPY . .(so the cachesurvives the source copy); no application code is touched.
🤖 Generated with Claude Code