Coolify deploys were failing with exit 255 (kernel OOM, no Docker error)
around the 73s mark of `next build`. Root cause: docker/Dockerfile's three
build stages (web-build, collab-build, mcp-build) all `FROM deps`, and
BuildKit was running them in parallel. The web-build alone wants ~3 GB
heap (capped at 5120 MB) and was racing tsup workers + buildkit + dockerd
on an 8 GB host until the kernel reaped it.
docker-compose.coolify.yml already had a comment claiming `depends_on:
[collab, mcp]` on `web` would serialize the builds. It doesn't —
`depends_on` only orders runtime startup, not `docker compose build`.
Fix: enforce ordering inside the Dockerfile DAG by COPYing one trivial
artifact from each lighter stage into web-build. BuildKit now waits for
collab-build and mcp-build to finish before starting the heavy Next.js
compile, which then gets the host effectively to itself. The copied
files land in /tmp and are never read by the runtime web image.
Also updated the compose comment to reflect the new (and accurate)
ordering mechanism.
Co-authored-by: Cursor <cursoragent@cursor.com>
CT 107 bumped to 8 GB RAM. Capping the heap below the available memory
makes V8 GC-thrash near the limit and contributes to oom-kills. Set
--max-old-space-size to 5120 MB (~60% of host) so the compile has real
headroom while leaving room for kernel + dockerd + buildkit + tsup workers.
Made-with: Cursor
The 1.5GB heap cap was actually too aggressive for the Next 15 webpack
compile on this monorepo: V8 spirals into GC churn near the cap, runs
the host out of free memory, and oom-killer SIGKILLs the build (exit 255).
With 4GB on the host now:
- Cap V8 heap at 2.5GB (~70% of host RAM) — gives the compile real
headroom while leaving room for kernel + dockerd + concurrent COPY
layers from the collab/mcp runtime stages.
- Add depends_on so the lighter collab + mcp services finish building
before the web target starts its peak-memory compile, instead of
fighting it for memory in parallel.
Made-with: Cursor
next build was OOM-killed (exit 255) on the Coolify host during
'Linting and checking validity of types' — tsc pulls the whole type graph
into memory and pushes the build past available RAM.
Type-checking and linting belong in CI / pre-commit, not in the prod
container build. Skip them via next.config and cap the Node heap to 1.5 GB
so any future memory blow-up surfaces as a JS OOM instead of a SIGKILL.
Made-with: Cursor
Collapse Dockerfile.web / Dockerfile.collab / Dockerfile.mcp into a single
docker/Dockerfile with shared `deps` stage and `web` / `collab` / `mcp`
runtime targets. BuildKit hashes the deps stage identically for all three
targets, so `pnpm install` runs once instead of three times in parallel —
fixes the OOM kill on the Coolify host (CT 107) during `docker compose build`.
Both docker-compose.yml (local dev) and docker-compose.coolify.yml now
select services via `target:` instead of separate dockerfile paths.
Made-with: Cursor