MiniBox uses a content-addressed layer cache to avoid re-executing build steps whose inputs have not changed. When a block’s cache key matches an existing directory underDocumentation 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.
DataRoot/layers/, the block is reported as CACHED and its entire instruction set is skipped — including network calls, compilations, and package installs.
Understanding how the cache key is computed helps you structure blocks for maximum cache reuse and faster iteration cycles.
Cache Key Formula
Every block produces a single SHA-256 hash that acts as its cache key. The hash is computed from a concatenated string of all the inputs that could affect the block’s output:parentHash chains the base image identity into every block, so a change to BASE cascades to all blocks even if none of their own instructions changed.
The cache key is computed entirely from inputs — it does not depend on the current timestamp, hostname, or any external state. This makes builds fully reproducible across machines that share the same
DataRoot.Cache Key Components in Detail
parentHash — base image chaining
parentHash — base image chaining
The This means the
parentHash starts as SHA256(cfile.BaseImage) — a hash of the base image string (e.g. "alpine:latest"). After each wave of blocks completes, the scheduler folds their names into the running hash:parentHash passed to a block implicitly encodes the entire prior build history, not just the base image.Dependency names — NEED edge sensitivity
Dependency names — NEED edge sensitivity
The block’s
NEED names are included in the hash string as a comma-joined list. This means that if you rename a dependency block or add/remove a NEED edge, the cache is automatically busted for all downstream blocks.Inherited workdir
Inherited workdir
The workdir propagated from dependency blocks is part of the key. If a
NEED block’s final WORKDIR changes, all blocks that inherit from it will recompute — preventing the subtle bug of a block running in the wrong directory from a stale cache.Instruction stream
Instruction stream
Every instruction in the block is serialised as
<TYPE><args joined> and concatenated. The order matters — swapping two RUN commands produces a different key even if the commands are identical.COPY source content hash — file change detection
COPY source content hash — file change detection
For every
COPY <src> <dest> instruction, MiniBox computes a recursive directory hash of the source path on the host (utils.HashDir(src)) and appends it to the instruction stream. This is the critical piece that ensures a source code change busts the cache for the source block — even though the instruction text COPY . /app never changes.For COPY FROM=<block> instructions, the dependency block’s layer directory base name (which is itself a content hash) is used instead.AUTO-DEPS flag
AUTO-DEPS flag
If the block has
auto-deps set, the literal string "auto-deps" is appended to the key stream. This ensures that adding or removing auto-deps from a block always invalidates its cache.Layer Storage Location
Built layers are stored as plain directories under:<hash> is the 64-character hex SHA-256 cache key. The default DataRoot is /var/lib/minibox unless overridden by MINIBOX_DATA_ROOT.
A special marker file signals that a layer was successfully completed:
Full DataRoot Layout
Cache Hits and Misses
A block hits the cache ifDataRoot/layers/<hash>/.minibox_layer_complete exists. The build log shows the result for every block:
[dag-summary] line at the end of a build shows totals:
What Triggers a Cache Miss
Source file change
Any file under a
COPY source path is modified, added, or deleted. utils.HashDir walks the entire tree and includes file content in the hash.Instruction change
An instruction is added, removed, modified, or reordered within a block. Even a whitespace change in a
RUN command busts the cache.Dependency rename or reorder
A
NEED block is renamed or the list of NEED dependencies changes.BASE image change
The
BASE directive references a different image tag. The parentHash changes and cascades to all blocks.Inherited workdir change
A dependency block’s final
WORKDIR changes, altering the inherited workdir key component.Build cache cleared
minibox system prune --build-cache removes all DataRoot/layers/ directories, forcing a full rebuild.Clearing the Build Cache
The build cache is separate from the OCI image store. Removing an image withminibox rmi deletes the manifest and blobs from index.json / blobs/sha256/ but leaves layers/ intact. This allows a rebuilt image to reuse cached block layers even after the previous image was removed.
To force a complete rebuild of all blocks:
DataRoot/layers/ directory tree. The next build will recompute every block from scratch, repopulating the cache as it goes.
To remove both the build cache and all container/image data:
Performance Flag: MINIBOX_INDEX_LAYERS
After a block layer is saved, MiniBox optionally runs an async indexing pass (viastorage.IndexLayer) that builds a lookup structure for lazy layer loading. For large layers — particularly node_modules — this indexing can be expensive.
Set MINIBOX_INDEX_LAYERS=0 to disable it entirely and speed up the [finalize] phase:
Indexing runs asynchronously in a goroutine and does not block the build from completing. The savings are primarily visible on large layer directories. For most small images the difference is negligible.
Tips for Maximising Cache Hits
Isolate source from deps
Keep
COPY . /app in a dedicated source block. This way, source changes only bust the source block — the deps block (with slow npm install) stays cached until package.json actually changes.Put stable steps first
System package installation (
pkg nodejs) changes rarely. Place it in an early block with no NEED dependencies so it is the most cache-stable node in the graph.Use .miniboxignore
Create a
.miniboxignore file to exclude build artefacts, .git, and node_modules from COPY source hashing. Unnecessary files in the hash increase the chance of spurious cache misses.Avoid broad COPY in dep blocks
Only
COPY the exact files a block needs. COPY ./package.json instead of COPY . means a change to src/ does not bust the deps block cache.Pin package versions
pkg nodejs@20 pins to a specific version. Unpinned packages can cause cache misses when the latest version changes in the Alpine repository.Share a DataRoot across builds
The cache is stored on disk under
DataRoot. Builds running in CI with a persistent DataRoot (e.g., mounted volume) benefit from layers cached by previous runs.