LearnNewsExamplesServices
Frontmatter
id12017
titleMissing root .dockerignore: ai/deploy build context inflates to 90 GB
stateClosed
labels
bugaibuild
assigneesneo-gpt
createdAtMay 26, 2026, 12:27 PM
updatedAtJun 21, 2026, 3:48 PM
githubUrlhttps://github.com/neomjs/neo/issues/12017
authorneo-opus-ada
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtMay 26, 2026, 1:37 PM

Missing root .dockerignore: ai/deploy build context inflates to 90 GB

neo-opus-ada
neo-opus-ada commented on May 26, 2026, 12:27 PM

Context

Fourth friction signal from the first-real-world cloud-deployment exercise (siblings: #12014 #12015 #12016). Predecessor #10964 named this gap explicitly under "Docker context hygiene" and listed it as an AC, but the .dockerignore piece never shipped while other ACs from that ticket did land (Node 24 baseline, config bootstrap via initServerConfigs.mjs). Closing #10964 left this AC unfulfilled.

The symptom in the field: docker compose -f ai/deploy/docker-compose.yml build from a working neo checkout sends 20+ GB to the Docker daemon before crashing on disk-full inside the VM. The build cannot complete on any operator workstation that runs the actual Agent OS swarm against the same checkout.

The Problem

The canonical compose ai/deploy/docker-compose.yml:39-41 sets the build context to the repo root:

build:
  context: ../..
  dockerfile: ai/deploy/Dockerfile

Docker uses the .dockerignore at the build-context root, not next to the Dockerfile. The existing ai/deploy/.dockerignore is therefore never consulted for image builds via this compose stack:

node_modules
.neo-ai-data
dist
docs/output
.git
.github
*.log

V-B-A on a live neo checkout (dev HEAD, on a maintainer machine that runs the Agent OS swarm):

du -sh /path/to/neo .git node_modules dist .claude .neo-ai-data
 90G	(total)
 18G	.git
888M	node_modules
622M	dist
 21G	.claude
 48G	.neo-ai-data

Without a root .dockerignore, the legacy Docker builder (and even BuildKit's COPY . . step) sends/copies the entire 90 GB tree into the build context and the image layer. Concrete failure surfaced in the field: legacy build crashed after sending 20+ GB context with Error response from daemon: write /.git/objects/...: no space left on device against a default-sized Colima VM (100 GB disk).

The Architectural Reality

Affected:

  • Missing: /.dockerignore (build-context root). The single fix surface.
  • Drift: ai/deploy/.dockerignore is unreachable under the current compose context configuration. Either delete it (single-source-of-truth in the root) or document it as a fallback for direct docker build -f ai/deploy/Dockerfile ai/deploy/ invocations.
  • Excluded from existing siblings: .claude/ (21 GB of Claude Code worktrees + agent state) is not in ai/deploy/.dockerignore and would still leak even if that file were correctly placed.

The Dockerfile contract that depends on this:

COPY package*.json ./
RUN npm ci --ignore-scripts
COPY . .                              # ← 90 GB without .dockerignore
RUN npm rebuild better-sqlite3 && node ./ai/scripts/setup/initServerConfigs.mjs

The Fix

Add /.dockerignore at the repo root with at minimum:

<h1 class="neo-h1" data-record-id="6">Runtime / agent state — host-only, never deployed</h1>

.neo-ai-data
.claude

<h1 class="neo-h1" data-record-id="7">Build / test artifacts — rebuilt in-container</h1>

node_modules
dist
docs/output
coverage

<h1 class="neo-h1" data-record-id="8">Git substrate — image never needs git history</h1>

.git
.github

<h1 class="neo-h1" data-record-id="9">Logs + macOS noise</h1>

*.log
.DS_Store

The deploy image only consumes tracked source (ai/, buildScripts/, learn/, src/, test/ selectively, etc.) plus package*.json. A whitelist-shaped .dockerignore (exclude everything, then !include) is an option for stricter hygiene, but the blacklist above matches the existing ai/deploy/.dockerignore shape extended with .claude/.

Sibling cleanup decisions (optional, can be in same PR or follow-up):

  1. Delete ai/deploy/.dockerignore and replace with a one-line readme/comment in the deploy dir pointing at the canonical root file.
  2. OR keep both and add a note in ai/deploy/.dockerignore clarifying it is only consulted when builds run with ai/deploy/ as the context root (rare).

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
/.dockerignore (new file) Docker build-context semantics; ai/deploy/docker-compose.yml:39-41 build-context contract; #10964 unfulfilled AC Exclude .git, .claude, .neo-ai-data, node_modules, dist, docs/output, coverage, .github, logs, OS metadata None — image build cannot succeed against a working maintainer checkout without this Sibling ai/deploy/.dockerignore listing du -sh evidence: neo dir 90 GB, current build context sends entire tree
ai/deploy/.dockerignore Same Either retire (single-source-of-truth in root) or annotate as fallback for direct docker build -f ai/deploy/Dockerfile ai/deploy/ callers Keep as-is, root .dockerignore takes precedence under compose Inline comment File present, currently unused by compose-driven builds

Decision Record impact

aligned-with ADR 0014 — completes deployment substrate hygiene under existing cloud-topology authority. No ADR successor risk.

Acceptance Criteria

  • /.dockerignore exists at the neo repo root.
  • Excluded paths cover at minimum: .git, .claude, .neo-ai-data, node_modules, dist, docs/output, coverage, *.log, .DS_Store.
  • docker compose -f ai/deploy/docker-compose.yml --profile cloud --profile local-model build succeeds from a working maintainer checkout that runs the local Agent OS swarm (regression guard against the disk-full crash this ticket targets).
  • Build-context size reported by docker compose build (or equivalent) is < 100 MB after the fix.
  • Disposition of ai/deploy/.dockerignore is decided: retired with replacement comment, OR retained with explicit "fallback only" annotation.

Out of Scope

  • BuildKit / buildx adoption (orthogonal — BuildKit improves caching + parallelism but still needs .dockerignore to avoid the COPY . . bloat).
  • Image-size optimization beyond the .dockerignore win (multi-stage tuning, base-image slimming, etc.).
  • Per-service Dockerfile context narrowing (e.g., narrowing the kb-server context to only ai/mcp/server/knowledge-base/ + shared deps) — viable future optimization but out of scope for this fix.
  • Tracked-source whitelist (!-rule shape) instead of blacklist — defer to a follow-up if blacklist proves brittle.

Avoided Traps

  • Filing as enhancement — rejected; this is a correctness bug. Cloud-deployment build is unbuildable from any neo checkout that actually runs the swarm (the only kind of checkout that has the failure-inducing runtime artifacts present).
  • Re-opening #10964 — rejected per skill §11 (authorship respect; original closed by another author). Filing as targeted follow-up is the correct disposition.
  • Whitelist-shaped .dockerignore (exclude-all-then-allow) — rejected for the first cut; matches ai/deploy/.dockerignore's blacklist shape for consistency. Whitelist can be a follow-up if blacklist drift becomes a maintenance problem.
  • Moving the Dockerfile out of ai/deploy/ to change the canonical context — rejected; ADR 0014 owns the topology placement.

Related

  • #10964 — predecessor (closed); named the .dockerignore gap as an AC, other ACs landed but this one did not.
  • #12014 — sibling first-real-world-deployment friction (orchestrator co-location follow-up).
  • #12015 — sibling Day-0 macOS prerequisites friction.
  • #12016 — sibling compose interpolated cpus/memory quoting.
  • ADR 0014 — cloud-deployment topology (substrate authority for the deploy substrate).

Handoff Retrieval Hints

  • Grep: find . -maxdepth 2 -name '.dockerignore' — pre-fix returns only ai/deploy/.dockerignore; post-fix returns root + sibling (or root only if sibling is retired).
  • Disk evidence: du -sh .git .claude .neo-ai-data on any maintainer checkout demonstrates the 90 GB context problem.
  • Semantic: ".dockerignore root build context inflated", "ai/deploy build no space left on device".
  • File anchor: ai/deploy/docker-compose.yml:39-41 (build-context contract).
tobiu referenced in commit 55865f8 - "fix(deploy): restore cloud compose buildability (#12014, #12016, #12017, #12019) (#12018) on May 26, 2026, 1:37 PM
tobiu closed this issue on May 26, 2026, 1:37 PM