MiniBox models every image build as a Directed Acyclic Graph (DAG) where eachDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/chaitu426/minibox/llms.txt
Use this file to discover all available pages before exploring further.
BLOCK is a node and each NEED / BNEED directive is a directed edge. Instead of running stages one-by-one like a traditional linear build, MiniBox identifies which blocks have all their dependencies satisfied and runs them concurrently — shrinking wall-clock build time dramatically on multi-core machines.
What Is a DAG Build?
A Directed Acyclic Graph is a structure where nodes are connected by one-way edges and no path can loop back to its starting node. In a MiniBox build:- Nodes are
BLOCKdefinitions. - Edges are
NEEDandBNEEDdirectives inside those blocks. - No cycles are allowed — the builder will error with
circular or unsatisfiable block dependencies detectedif it finds one.
Without DAG
Sequential builds run one stage at a time — earlier stages block later ones even when they share no data.
With DAG
Independent blocks execute in parallel. Total time collapses to the length of the critical path, not the sum of all stages.
Wave-Based Execution Model
The DAG scheduler (buildFromBlocks in internal/builder/builder.go) operates in discrete rounds called waves:
Compute the ready set
Scan all blocks that have not yet been built. A block is ready when every block listed in its
NEED and BNEED lists has already completed. All ready blocks form the current wave.Launch goroutines
Every block in the wave is dispatched as a concurrent Go goroutine. Each goroutine gets a per-line prefixed writer (
[blockname] …) so log output from parallel blocks never interleaves mid-line.Wait for the wave
The scheduler blocks until every goroutine in the wave reports success or failure. A single block failure aborts the entire build.
Example: Four-Block Node.js Build
| Wave | Blocks | Runs concurrently? |
|---|---|---|
| 1 | runtime, source | ✅ Yes — no dependencies |
| 2 | deps | ✅ Alone, but unblocked immediately after Wave 1 |
| 3 | config | ✅ Alone, unblocked after Wave 2 |
max(runtime, source) + deps + config, not their sum.
NEED vs BNEED Edges in the DAG
Both directives create a dependency edge — the block they name must complete before the current block can start. They differ in what they contribute to the final image:NEED — Layer-inclusive edge
The dependency block’s filesystem layers are included in the final exported image beneath the current block’s layer.
BNEED — Build-only edge
The dependency block must complete first, but its layers are excluded from the final image. Artifacts must be explicitly copied with
COPY FROM=.NEED edges from that target. Any block only referenced via BNEED (and not also via NEED) is pruned automatically.
Build Log Format
The structured log stream lets you trace exactly what the DAG scheduler is doing in real time.Log Prefix Reference
| Prefix | Emitted by | Meaning |
|---|---|---|
[build] | Build pipeline | Overall build start / mode / done |
[base] | Base image resolver | Base image fetch / cache status |
[dag] | DAG scheduler | Wave start, wave done with stats |
[dag-summary] | DAG scheduler | Final totals: blocks, cached, built |
[block-name] | Per-block goroutine | START, CACHED, DONE, and all instruction output |
[finalize] | OCI writer | Layer tar+gzip and manifest generation |
Block Status Lines
Each block emits exactly one of these status lines:Best Practices for DAG Block Structure
Canonical Four-Block Pattern
This structure maximises cache reuse and parallelism for most application types:source from deps? If they were merged, every source change would re-run npm install / pip install. Keeping them separate means only the source block’s cache is busted — deps stays cached unless package.json or requirements.txt actually changes (because COPY source content is part of the cache key).
Parallelism Tips
Maximise Wave 1
The more blocks you can place at Wave 1 (no dependencies), the more parallel work happens immediately. Use
NEED only when the data dependency is real.Avoid fat NEED chains
A → B → C → D is a serial chain with zero parallelism. Ask whether each NEED is truly necessary or whether a BNEED + COPY FROM= would achieve the same result without carrying layers.AUTO-DEPS Language Detection
When a block containsauto-deps, MiniBox inspects the current workdir inside the overlay filesystem and runs the first matching installer it finds:
Node.js
Detects:
package.jsonRuns: npm installInstalls all dependencies listed in package.json into node_modules within the current workdir.Python
Detects:
requirements.txtRuns: pip install -r requirements.txtInstalls Python packages listed in the requirements file.Go
Detects:
go.modRuns: go mod downloadDownloads all module dependencies declared in go.mod into the module cache.Rust
Detects:
Cargo.tomlRuns: cargo buildCompiles the Cargo project and all its dependencies.auto-deps always runs after all other instructions in the block have been executed, regardless of where auto-deps appears in the block. The manifest file must be present in the workdir before auto-deps executes — supply it via a NEED dependency or an explicit COPY earlier in the same block:
Cycle Detection
If the dependency graph contains a cycle or an unsatisfiable dependency (aNEED referencing a block that does not exist), the scheduler will error before any build work starts:
- All
NEEDandBNEEDarguments match exactly aBLOCKname defined in the same file (case-sensitive). - No block (directly or transitively) depends on itself.