如何在Nix(尤其nix-env中)生成可复现的配置锁定文件?
Great question! Achieving reproducible environments in Nix that mirror the lock file functionality you know from npm/yarn or Python is totally feasible. Let’s walk through the most practical approaches to get that precise, repeatable setup with your my-env.nix:
1. Use Flakes (Recommended, Official Modern Approach)
Flakes are Nix’s built-in solution for reproducibility, generating a flake.lock file exactly like the lock files you’re familiar with. This file pins all dependencies (including nixpkgs itself) to specific revisions with cryptographic hashes, ensuring every install pulls identical packages.
Steps to set this up:
Enable Flakes (if you haven’t already): Add these lines to your
~/.config/nix/nix.conf(or/etc/nix/nix.conffor system-wide):experimental-features = nix-command flakesRestart your Nix daemon (for system installs) or re-login to apply the change.
Create a
flake.nixalongside yourmy-env.nix:{ description = "My reproducible development environment"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # Or your preferred nixpkgs channel }; outputs = { self, nixpkgs }: { # Expose your environment as a package packages.x86_64-linux.my-env = nixpkgs.legacyPackages.x86_64-linux.callPackage ./my-env.nix {}; # Optional: Create an interactive dev shell devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell { packages = [ self.packages.x86_64-linux.my-env ]; }; }; }Adjust the architecture (
x86_64-linux) if you’re on a different system (e.g.,aarch64-darwinfor M-series Macs).Generate the lock file:
Run either command to triggerflake.lockcreation:nix develop # Starts an interactive shell with your env and creates flake.lock # OR nix build .#my-env # Builds your environment package and creates flake.lockReproduce the environment later:
With bothflake.nixandflake.lockpresent, run:nix-env -if .#my-envThis installs exactly the same package versions as when you generated the lock file.
2. Use nix-lock for Non-Flake Environments
If you prefer sticking with traditional Nix expressions (no Flakes), the nix-lock tool can generate a lock file for your my-env.nix to pin all dependencies.
Steps:
Install
nix-lock:nix-env -iA nixpkgs.nix-lockGenerate the lock file:
Run this in the same directory asmy-env.nix:nix-lock my-env.nixThis creates a
my-env.lockfile with all dependency hashes.Install using the lock file:
To ensure you use the locked versions, run:nix-env -if <(nix-lock --apply my-env.nix my-env.lock)The
--applyflag injects the locked hashes into your original expression before installation.
3. Manual Locking (Not Recommended, For Reference)
You can manually generate a locked expression by resolving all dependencies to their exact store paths, but this is cumbersome and hard to maintain. For completeness, here’s how it works:
# Get all dependencies of your environment nix-store -qR $(nix-instantiate my-env.nix) > dependencies.txt # Then create a new expression that references these exact store paths
This works, but updating dependencies requires repeating the entire process, so it’s better to use Flakes or nix-lock.
内容的提问来源于stack exchange,提问作者bbarker

