feat(devpkg): configurable Nix binary cache via DEVBOX_NIX_BINARY_CACHE#2891
Open
abueide wants to merge 2 commits into
Open
feat(devpkg): configurable Nix binary cache via DEVBOX_NIX_BINARY_CACHE#2891abueide wants to merge 2 commits into
abueide wants to merge 2 commits into
Conversation
Devbox hardcodes https://cache.nixos.org as the binary cache it queries for prebuilt package outputs. This URL is used in two places: 1. The narinfo HEAD precheck in devpkg.readCaches / fetchNarInfoStatusFromHTTP, which runs unconditionally on every `devbox run` (via FillNarInfoCache). 2. The fromStore of the builtins.fetchClosure expressions in the generated flake.nix. In a network-restricted environment (e.g. an enterprise CI runner with no public egress) cache.nixos.org is unreachable, so the precheck HEAD request times out. Because fetchNarInfoStatusFromHTTP returns the error and fetchNarInfoStatusOnce propagates it, `devbox run` fails hard with `Head "https://cache.nixos.org/<hash>.narinfo": context deadline exceeded` even when an internal mirror that serves the identical store paths is available and configured as a Nix substituter. (Setting `substituters` in nix.conf does not help: builtins.fetchClosure contacts fromStore directly and ignores substituters.) Add a DEVBOX_NIX_BINARY_CACHE environment variable that overrides the default cache, following the same pattern as the existing DEVBOX_SEARCH_HOST override (envir.GetValueOrDefault). When unset, behavior is unchanged (https://cache.nixos.org), so this is fully backwards compatible. The override flows to both consumers: readCaches seeds its list with the resolved cache, and the flake template now sets fromStore to the http(s) cache the output was actually found in (via a new fetchClosureStore template helper), falling back to the configured binary cache for s3 caches that fetchClosure cannot use directly. Pointed at an internal mirror that proxies cache.nixos.org, `devbox run` then works with no public egress.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR makes Devbox’s Nix binary cache configurable via DEVBOX_NIX_BINARY_CACHE, replacing the previously hardcoded https://cache.nixos.org in both the Go-level narinfo precheck and the generated flake.nix builtins.fetchClosure fromStore value. This enables devbox run to work in network-restricted environments when an internal mirror/proxy is available.
Changes:
- Introduces
envir.DevboxNixBinaryCacheanddevpkg.BinaryCache()(defaulting tohttps://cache.nixos.org, overridable via env var). - Updates narinfo cache discovery to seed read caches from
devpkg.BinaryCache()instead of a constant. - Updates flake generation to set
fromStorebased on the cache URI actually used, with tests added for bothBinaryCache()andfetchClosureStore()behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/shellgen/tmpl/flake.nix.tmpl | Uses fetchClosureStore to dynamically set builtins.fetchClosure.fromStore. |
| internal/shellgen/generate.go | Adds fetchClosureStore template helper and wires it into template functions. |
| internal/shellgen/generate_internal_test.go | Adds unit tests for fetchClosureStore. |
| internal/envir/env.go | Registers the new DEVBOX_NIX_BINARY_CACHE env var constant with documentation. |
| internal/devpkg/narinfo_cache.go | Adds BinaryCache() and uses it to seed cache URIs instead of a hardcoded constant. |
| internal/devpkg/narinfo_cache_test.go | Adds unit tests for BinaryCache() default/override behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address review feedback:
- Render the fetchClosure fromStore through a nixString helper that escapes
backslash, double quote, and the ${ antiquotation, so a configured cache URL
(DEVBOX_NIX_BINARY_CACHE) with special characters can't break flake
evaluation or be interpreted as Nix interpolation. Output is unchanged for
ordinary URLs.
- TestFetchClosureStore now always sets DEVBOX_NIX_BINARY_CACHE (empty when
unset) so it can't be affected by the caller's environment.
- Add TestNixString.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #2599.
Devbox hardcodes
https://cache.nixos.orgas the Nix binary cache it queries for prebuilt package outputs. This makesdevbox runfail in network-restricted environments (such as enterprise CI runners with no public internet egress), even when an internal mirror that serves the identical store paths is configured as a Nix substituter.The hardcoded URL (
internal/devpkg/narinfo_cache.go) is used in two places:readCachesseeds its cache list with this URL, andFillNarInfoCacheruns unconditionally at the start of everydevbox run(viaflakePlan).fetchNarInfoStatusFromHTTPdoes a 5sHEADto<cache>/<hash>.narinfo; on a network error it returns the error, andfetchNarInfoStatusOncepropagates it.fromStoreof thebuiltins.fetchClosureexpressions in the generatedflake.nix.So on a locked-down runner,
devbox runfails hard with:…even when the toolchain is fully available from an internal substituter. Setting
substitutersinnix.confdoes not help:builtins.fetchClosurecontacts itsfromStoredirectly and ignoressubstituters, and the Go-level precheck has its own hardcoded URL.This PR adds a
DEVBOX_NIX_BINARY_CACHEenvironment variable that overrides the default cache, following the same pattern as the existingDEVBOX_SEARCH_HOSToverride. When unset, behavior is unchanged (https://cache.nixos.org), so this is fully backwards compatible. Pointed at an internal mirror that proxiescache.nixos.org,devbox runthen works with no public egress:Changes
envir: add aDevboxNixBinaryCache(DEVBOX_NIX_BINARY_CACHE) constant to the central env-var registry.devpkg: replace thebinaryCacheconstant with aBinaryCache()accessor that resolves the env var viaenvir.GetValueOrDefault, defaulting tohttps://cache.nixos.org;readCachesuses it.shellgen: the generated flake'sfromStorenow uses the http(s) cache the output was actually found in, via a newfetchClosureStoretemplate helper that falls back to the configured binary cache fors3://cachesfetchClosurecannot use directly.How was it tested?
TestBinaryCache(internal/devpkg) covers the default and the override;TestFetchClosureStore(internal/shellgen) covers http(s) pass-through, the s3 fallback, and the configured fallback.DEVBOX_NIX_BINARY_CACHEset, the generatedflake.nixemitsfromStore = "<mirror>"and the narinfo precheck targets the mirror; unset, it remainshttps://cache.nixos.org.Community Contribution License
All community contributions in this pull request are licensed to the project
maintainers under the terms of the
Apache 2 License.
By creating this pull request, I represent that I have the right to license the
contributions to the project maintainers under the Apache 2 License as stated in
the
Community Contribution License.