NIX_REMOTE, --store, --eval-store Interaction¶
Source: Nix repo, current HEAD.
Configuration Sources¶
Source |
What it sets |
Code location |
|---|---|---|
|
|
|
|
|
|
|
|
|
How Stores Are Created¶
Builder store (--store / NIX_REMOTE)¶
StoreCommand::getStore() → StoreCommand::createStore() → StoreConfigCommand::createStoreConfig() returns resolveStoreConfig(settings.storeUri.get()) (src/libcmd/command.cc:78).
resolveStoreConfig in src/libstore/store-registration.cc:26-76 handles the "auto" case:
If
$NIX_STATE_DIRis writable →LocalStoreElse if
nixDaemonSocketFileexists →UDSRemoteStore(connects to daemon)Else on Linux, non-root, without overrides → chroot store in
~/.local/share/nix/rootElse fallback →
LocalStore
Eval store (--eval-store)¶
EvalCommand::getEvalStore() (src/libcmd/command.cc:159-163):
evalStore = evalStoreUrl ? openStore(StoreReference{*evalStoreUrl}) : getStore();
If --eval-store is absent, it reuses the same store as --store/NIX_REMOTE. If present, it opens a completely independent store connection.
How nix build Wires Them Together¶
CmdBuild inherits: InstallablesCommand → SourceExprCommand → MixFlakeOptions → EvalCommand → MixEvalArgs
The run() method in src/nix/build.cc:141 calls:
Installable::build(getEvalStore(), store, Realise::Outputs, installables, ...);
This flows into Installable::build2() (src/libcmd/installables.cc:600) which calls store->buildPathsWithResults(paths, bMode, evalStore).
LocalStore path¶
Store::buildPathsWithResults (src/libstore/build/entry-points.cc:49) creates a Worker(*this, evalStore ? *evalStore : *this). The Worker uses worker.evalStore throughout the build lifecycle:
worker.evalStore.readDerivation(path)— resolving derivation metadataworker.evalStore.queryPartialDerivationOutputMap(path)— checking what outputs existCopying input sources from eval store to build store (
derivation-building-goal.cc:81-91)Checking validity and adding temp roots on eval store
RemoteStore path¶
RemoteStore::buildPathsWithResults (src/libstore/remote-store.cc:583) first calls copyDrvsFromEvalStore() (src/libstore/remote-store.cc:550-568):
void RemoteStore::copyDrvsFromEvalStore(const std::vector<DerivedPath> & paths,
std::shared_ptr<Store> evalStore) {
if (evalStore && evalStore.get() != this) {
RealisedPath::Set drvPaths2;
for (const auto & i : paths) {
std::visit(overloaded{
[&](const DerivedPath::Built & bp) { drvPaths2.insert(bp.drvPath->getBaseStorePath()); },
[&](const DerivedPath::Opaque &) { /* assume already there */ },
}, i.raw());
}
copyClosure(*evalStore, *this, drvPaths2);
}
}
Then sends WorkerProto::Op::BuildPathsWithResults to the remote daemon with the derived paths. The remote daemon is expected to fetch or build those paths.
Important caveats¶
Store type |
|
|---|---|
|
Supported — copies |
|
Supported — Worker uses eval store directly |
|
Not supported — throws error ( |
|
Not supported — asserts |
Practical Use¶
# Default: everything on one daemon
NIX_REMOTE=daemon nix build .#myPackage
# Explicit equivalent
nix build --store daemon .#myPackage
# Split: eval on one daemon, build on another
nix build \
--eval-store unix:///path/to/eval-daemon \
--store unix:///path/to/builder-daemon
# Eval-store alone: eval daemon != build daemon
nix build \
--eval-store unix:///path/to/eval-daemon \
.#myPackage
When --eval-store and --store differ:
Evaluation reads
.drvfiles and source from the eval storeOnly the
.drvclosure (derivations + their direct inputs) is copied to the builder store viacopyClosureBuild execution and output storage happen on the builder store
The eval store is consulted for derivation metadata during the build (output hashes, input derivation resolution)
Source inputs not already in the builder store are copied there on demand (
derivation-building-goal.cc:81-91)