-
Notifications
You must be signed in to change notification settings - Fork 1
Packing
Some machines can't reach your conda channels — isolated build hosts, secure enclaves, offline labs. Packing bundles everything an environment needs into one file you can copy across the gap and install with no network and no conda.
A bundle is a .tar archive containing the lock, a manifest, and every package
archive the lock pins:
nepenthe-pack.yml # format, environment, platforms, packages (file + sha256 + size)
environment.lock # the lock that was packed
pkgs/<filename> # every .conda / .tar.bz2 the lock references
Packages inside .conda archives are already compressed, so the outer tar is
left uncompressed.
pack reads a lock, downloads every package it pins, verifies each against the
lock's recorded sha256, and writes the bundle:
# pack every platform the lock covers for the "app" environment
nepenthe pack --lock app.lock --env app --output app.tar
# packed app (linux-64) — 39 packages, 65.6 MiB → app.tar
# …or restrict to specific platforms (repeat --platform)
nepenthe pack --lock app.lock --env app \
--platform linux-64 --platform osx-arm64 --output app.tarA lock with multiple platforms shares noarch packages between them, so they are bundled once.
Copy the .tar across, then install from it. unpack extracts the bundle,
rewrites every package URL to the bundle's local copy, and installs into a prefix
— offline, no conda:
nepenthe unpack --pack app.tar --prefix ./envs/app
# installed app (linux-64) at ./envs/app — 39 packages
# the environment defaults to the bundle's; override env/platform if needed
nepenthe unpack --pack app.tar --prefix ./envs/app \
--env app --platform linux-64 --stage-dir ./unpackedBy default the bundle is extracted to a temporary directory that is removed after
the install. Pass --stage-dir to keep the extracted packages (e.g. to install
several prefixes from one bundle without re-extracting).
The installed prefix is byte-identical to one created online from the same lock —
diff against the lock comes back empty.
import nepenthe
# producer host
summary = nepenthe.pack("app.lock", "app", "app.tar") # all platforms
summary = nepenthe.pack("app.lock", "app", "app.tar", platforms=["linux-64"])
print(summary["packages"], summary["bytes"])
# air-gapped host
nepenthe.unpack("app.tar", "./envs/app") # offline install
nepenthe.unpack("app.tar", "./envs/app", env="app", platform="linux-64")See the Python API for the full surface.
- Integrity end to end. Every package is verified against the lock's sha256 at pack time; rattler re-verifies the same hash when linking from the bundle at install time. A corrupt or tampered package is rejected.
-
No conda, no re-solve.
unpackrewrites each lock record's URL to afile://path inside the bundle; rattler's installer reads the local archive directly (get_or_fetch_from_path) and links it into the prefix. - Reproducible. The bundle carries the exact lock, so the air-gapped install matches the online one package for package.
-
Authenticated channels. Package downloads during
packare unauthenticated. Packing from a channel that requires credentials is not yet supported — pack from a public or already-permitted mirror. (Tracked for a future release.) - Size. A bundle contains the full package set, so it is as large as the environment (tens to hundreds of MiB). This is the cost of being self-contained.
This wiki is autogenerated. To made updates, open a PR against the original source file in docs/wiki.