Pin reproducible HPC builds with Spack environments
Use spack env create, concretize, and a committed spack.lock to install the same dependency graph on every machine.
29 Aug 2026, 14:39 UTC

You run spack install hdf5 on your workstation, then a colleague runs the same command on the cluster and gets a different MPI implementation, a different zlib variant, or a build failure. Ad-hoc Spack installs resolve dependencies independently each time, so the concrete dependency graph—the exact versions, compilers, and build options Spack actually builds—can drift between machines.
The useful takeaway is to create a Spack environment, add your specs, run spack concretize, and commit both spack.yaml and spack.lock. Anyone with those files can reproduce the same dependency graph.
Start with an environment, not a package
A Spack environment is a named directory that groups specs into a single concretization. Instead of installing packages one at a time, you declare the whole graph in one place.
Run these commands in a shell where Spack is initialized, such as after sourcing Spack's setup script. You need ordinary user permissions and write access to the directory where the environment is created. Replace repro-demo with your own environment name.
spack env create repro-demo
spack env activate repro-demo
spack add zlib
spack add hdf5
spack concretize
spack install
spack env deactivate
Activating an environment sets SPACK_ENV and changes module paths for the current shell. Other Spack commands in that shell target the environment until you deactivate it, which can interfere with unrelated work.
If concretization succeeds, Spack writes spack.yaml and spack.lock into the environment directory. The lock file records the concrete DAG: resolved compilers, MPI implementations, build dependencies, and variants.
Check the graph before you build
Concretization can be slow or fail when version and variant constraints conflict across the dependency graph. Run spack concretize and inspect the result before starting a long compile.
spack concretize
If it fails, loosen conflicting variants or remove incompatible specs. After installation, verify the graph with:
spack find --deps
A practical check is to run spack concretize a second time. It should report no changes if spack.lock already captures the current resolution.
Share the lock file, not just the intent
spack.yaml describes what you want; spack.lock records what Spack resolved. Commit both to version control. A teammate can clone the repository and run:
spack env create repro-demo --dir /path/to/cloned/repo
spack env activate repro-demo
spack install
Environment files are local by default. To avoid compiling from source on every machine, attach a build cache or mirror to the environment so already-built binaries are reused. Without a mirror, each user compiles the full graph locally.
These commands follow Spack 1.x-style environment workflows. Older Spack 0.x releases used different commands and YAML schemas, so run spack --version and spack env --help before adopting this process.
Limitations and rollback
Concretization may fail on complex constraint conflicts, and activating an environment changes shell variables that can affect other Spack invocations. Because spack install writes to the Spack install prefix, rollback means uninstalling packages inside the activated environment or removing the environment directory, then running spack env deactivate.
Start with one environment, one lock file, and one committed graph. Verify with spack find --deps before sharing it with your team.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.