Multi-platform locking#
This tutorial walks through locking a workspace for multiple platforms
so that teammates on Linux, macOS, and Windows all get reproducible
environments from the same conda.lock.
Prerequisites#
conda (>= 24.7) with conda-workspaces >= 0.4.0 installed
An existing workspace with a
conda.toml(see Your first project if you need one)
Declare your platforms#
If you are starting a new project, pass --platform (repeatable) to
workspace init:
conda workspace init --platform linux-64 --platform osx-arm64 --platform win-64
Or if you already have a conda.toml, edit the platforms list
directly:
[workspace]
name = "my-project"
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "win-64"]
[dependencies]
python = ">=3.11"
numpy = ">=1.26"
If you omit --platform during init, only your current platform is
added. The platforms list tells the lock command which subdirs to
solve for.
Add a platform to an existing workspace#
There is no dedicated CLI command to add a platform after the fact.
Edit the platforms array in your conda.toml directly:
[workspace]
platforms = ["linux-64", "osx-arm64", "win-64"] # added win-64
Then re-lock to generate solutions for the new platform:
conda workspace lock
If you only want to solve the newly added platform (faster for large workspaces), target it explicitly:
conda workspace lock --platform win-64
This writes a lockfile covering just win-64. To fold it into your
existing conda.lock that already covers the other platforms, use
--output and --merge:
conda workspace lock --platform win-64 --output conda.lock.win-64
conda workspace lock --merge "conda.lock.*"
Or simply re-run conda workspace lock without flags to regenerate
the full lockfile from scratch.
Generate the lockfile#
Run conda workspace lock from the project root:
conda workspace lock
This solves every environment for every declared platform and writes a
single conda.lock. On a macOS ARM machine it will solve for
linux-64 and win-64 in addition to osx-arm64, using conda’s
virtual package overrides to target the correct subdir.
The output looks something like:
Locking default for linux-64...
Locking default for osx-arm64...
Locking default for win-64...
Wrote conda.lock (3 environments × 3 platforms)
Lock a subset of platforms#
If you only need to refresh one platform (for example, after adding a
Linux-only dependency), pass --platform:
conda workspace lock --platform linux-64
This flag is repeatable:
conda workspace lock --platform linux-64 --platform osx-arm64
Unknown platforms (typos like lnux-64) are rejected before the
solver runs.
Add platform-specific dependencies#
Some packages only exist on certain platforms. Use [target] tables:
[target.linux-64.dependencies]
linux-headers = ">=5.10"
[target.osx-arm64.dependencies]
llvm-openmp = ">=14.0"
Re-run conda workspace lock and only the affected platforms pick up
the new packages.
Pin system requirements#
When cross-solving (for example, generating a linux-64 lock from
macOS), the solver needs to know target system constraints. Use the
[system-requirements] table:
[system-requirements]
glibc = "2.17"
This adds __glibc >=2.17 as a virtual package constraint for Linux
solves. Without it the solver may pick packages that require a newer
glibc than your deployment target.
You can also pin via environment variables for one-off overrides:
CONDA_OVERRIDE_GLIBC=2.17 conda workspace lock --platform linux-64
Handle unsolvable platforms#
Some combinations of dependencies are unsolvable on certain platforms
(a package might not be built for win-64 yet). By default the lock
command fails on the first broken solve. To keep going and lock what
you can:
conda workspace lock --skip-unsolvable
This prints a yellow Skipping ... line for each failed
(environment, platform) pair and writes the lockfile with the
successful solves. If every pair fails, no lockfile is written and the
command exits with an error.
Install from the lockfile#
On any machine, install the exact locked versions without re-solving:
conda workspace install --locked
This validates that the lockfile is still fresh relative to the
manifest. If you’ve changed conda.toml since locking, the install
fails and asks you to re-lock. To skip that check:
conda workspace install --frozen
Verify the platform set#
To see which platforms are reachable (workspace-level plus any feature-level additions):
conda workspace info
The text output shows a “Known Platforms” row when features expand
beyond the workspace default. The JSON form exposes this as
known_platforms:
conda workspace info --json | jq .known_platforms
Next steps#
Split locking across CI runners with
--outputand--merge(see CI pipeline)Add features with per-feature platform lists
Check the Lock section for all flags and error handling details