Environments
Environments are isolated roots: each has a channel (e.g. debian, alpine, fedora with optional version), its own set of installed packages, and a directory ebin where exposed binaries are linked. You can register environments so their ebin is added to your PATH, or use activate for the current shell only.
List environments
epkg env list
Example output:
Type Status Environment Root
=========-==============-===================================-================================
private __c__compass-ci__.eenv /c/compass-ci/.eenv
private __c__epkg__scripts__mirror__.eenv /c/epkg/scripts/mirror/.eenv
private aa /home/wfg/.epkg/envs/aa
private alpine /home/wfg/.epkg/envs/alpine
private archlinux /home/wfg/.epkg/envs/archlinux
private conda /home/wfg/.epkg/envs/conda
private debian /home/wfg/.epkg/envs/debian
private fedora /home/wfg/.epkg/envs/fedora
private registered@0 main /home/wfg/.epkg/envs/main
private openeuler /home/wfg/.epkg/envs/openeuler
private opensuse /home/wfg/.epkg/envs/opensuse
private ubuntu /home/wfg/.epkg/envs/ubuntu
Columns: Environment name, Type (private/public), Status (e.g. registered@ORDER). In shared store mode, other users’ public envs may appear with an owner prefix (e.g. root/envname).
Create an environment
epkg env create [ENV_NAME] [-c|--channel CHANNEL] [-P|--public] [-i|--import FILE]
- ENV_NAME — Name of the new environment.
- -c, --channel — Channel (e.g.
debian(default),ubuntu,alpine,fedora,openeuler,archlinux,conda). - -P, --public — Make the environment public (in shared store mode, other users can use it read-only as
owner/envname). - -i, --import — Import from a config file.
Examples:
epkg env create mydebian -c debian
# Creating environment 'mydebian' in $HOME/.epkg/envs/mydebian
epkg env create myalpine -c alpine
# Creating environment 'myalpine' in $HOME/.epkg/envs/myalpine
Create by path (--root)
You can create an environment at an arbitrary path; epkg generates a name from the path:
epkg env create --root /tmp/myproject/.eenv -c alpine
# Creating environment '__tmp__myproject__.eenv' in /tmp/myproject/.eenv
# Note: environment name was auto-generated from path
Using .eenv as the directory name enables implicit env discovery: from a script under that tree, epkg run ./script.sh (or epkg run /path/to/project/subdir/script.sh) can resolve the environment from the containing .eenv directory.
Remove an environment
epkg env remove [ENV_NAME]
If the env is registered, it is unregistered first. Example:
# Environment 'myenv' is not registered.
# Environment 'myenv' has been removed.
Register and unregister
Register adds the environment’s ebin to your default PATH (persisted across shells). Unregister removes it.
epkg env register [ENV_NAME] [--path-order N]
epkg env unregister [ENV_NAME]
After register, the command prints the new PATH; you can run eval "$(epkg env path)" in the current shell to apply it, or rely on your RC file if it sources epkg’s path helper.
Example:
epkg env register myalpine
# Registering environment 'myalpine' with PATH order 100
# export PATH="/home/user/.epkg/envs/myalpine/ebin:/home/user/.epkg/envs/main/ebin:..."
epkg env unregister myalpine
# export PATH="/home/user/.epkg/envs/main/ebin:..."
# Environment 'myalpine' has been unregistered.
--path-order — Lower number means earlier in PATH. Default is 100.
Activate and deactivate
Activate sets the environment for the current shell only (session-specific). Deactivate clears it.
epkg env activate [ENV_NAME]
epkg env deactivate
After activate, the shell’s PATH is updated so the activated env is preferred. Useful for temporary focus on one env without changing registered envs.
Path and config
-
Path — Print the current PATH that includes all registered (and optionally activated) envs. Order is:
- Activated envs (most recently activated first)
- Registered envs with lower
--path-orderfirst (prepend side) - Original/system PATH
- Registered envs with negative
--path-order(append side)
epkg env path # export PATH="/home/user/.epkg/envs/main/ebin:..." -
Config — View or edit per-env config:
epkg env config edit epkg env config get <key> epkg env config set <key> <value>Examples:
env_root,public(bool).
Selecting the environment for commands
For any command that operates on an environment, you can specify it with:
- -e, --env ENV_NAME — Name (e.g.
main,alpine) or, in shared store,owner/envname. - -r, --root DIR — Root directory of the env (e.g. after
env create --root /path).
If both are present, -r takes precedence.
If neither is given, epkg finds .eenv/ env, uses the activated env, or the registered envs (for run, the first env in PATH that provides the command), or falls back to main.
Examples:
epkg -e alpine install htop
epkg -e alpine list
epkg -e alpine run htop --version
epkg --root /tmp/myproject/.eenv run jq --version
Isolate modes and VMM selection for epkg run
When you run commands inside an environment, epkg can add extra isolation on top of the per‑env root filesystem:
- env (default) — User and mount namespaces with bind mounts of the environment over
/usr,/etc,/var,/run, etc. Provides isolation for compatibility; not a strong security boundary. - fs — The environment becomes the new root via
pivot_root; proc, tmpfs (/tmp, /dev), and other pseudo-filesystems are mounted under it. Stronger filesystem isolation. - vm — Run the command inside a lightweight VM with the environment root shared via virtiofs. See
docs/design-notes/sandbox-vmm.mdfor design and dependencies (VMM, kernel, virtiofsd, optional libkrun).
You select the sandbox mode per command:
epkg -e mydebian run --isolate=env bash
epkg -e mydebian run --isolate=fs python3 script.py
epkg -e mydebian run --isolate=vm bash
Or set a per‑env default in env_root/etc/epkg/env.yaml via:
# Make fs the default sandbox for this env
epkg -e mydebian env config set sandbox.isolate_mode fs
# After that, plain `epkg -e mydebian run <cmd>` uses fs unless you override --isolate
epkg -e mydebian run bash
User-level defaults can be set in ~/.epkg/config/options.yaml (same sandbox.isolate_mode key). CLI --isolate overrides both.
For the host‑side tools that sandboxing relies on (user namespaces and newuidmap/newgidmap), install a minimal set with:
cd /c/epkg
./bin/make.sh sandbox-depends
This pulls in the appropriate uidmap/shadow/shadow-uidmap package for your distro; see the Troubleshooting guide for user‑namespace errors.
Choosing a VMM backend (--vmm)
When you use --isolate=vm, epkg can try multiple VMM backends in order. Use
the --vmm option on epkg run to specify a comma-separated preference list:
# Prefer libkrun, fall back to QEMU
epkg -e myenv run --isolate=vm --vmm=libkrun,qemu bash
# Force QEMU even if libkrun support is compiled in
epkg -e myenv run --isolate=vm --vmm=qemu bash
Backend names:
- libkrun — libkrun-based microVM backend (only available when epkg is built
with the
libkrunfeature and sandbox-kernel is installed in the env). - qemu — QEMU + virtiofs backend.
If --vmm is omitted:
- With
libkrunenabled at build time, the default order islibkrun,qemu. - Without
libkrun, the default order isqemuonly.
If a backend fails (for example missing binaries or misconfiguration), epkg logs a warning and automatically tries the next backend in the list.
Public environments (shared store)
When epkg is used with a shared store (e.g. root with /opt/epkg), environments can be public. Other users can then:
- List them (they appear as
owner/envnameinepkg env list). - Use them read-only:
epkg -e owner/envname run <cmd>,epkg -e owner/envname search <pkg>, etc.
Creating with -P makes an env public. The main env cannot be public.
Store mode rules (self install)
- epkg self install can take
--store private|shared|auto. - auto (default): private if not root; shared if root.
Public/private only applies in shared store mode.
Best practices
Organize environments by purpose
- main — Default environment for general use
- project-name — Per-project environments with specific dependencies
- distro-name — Environments for trying packages from specific distributions
- tool-name — Environments for specific tools or toolchains
Use path-order for PATH ordering
When registering multiple environments, use --path-order to control which binaries take precedence:
epkg env register dev-env --path-order 5 # Earlier in PATH
epkg env register test-env --path-order 20 # Later in PATH
Lower numbers = earlier in PATH.
Project-specific environments
For projects that need isolated dependencies:
cd /path/to/project
epkg env create --root ./.eenv -c alpine
# Add to .gitignore: .eenv/
# Document in README: "Run: epkg run ./setup.sh"
This keeps project dependencies isolated and makes the project portable.
Clean up unused environments
Periodically review and remove environments you no longer need:
epkg env list
epkg env remove old-env
epkg gc # Clean up unused store files
See also
- Package operations — Installing packages in environments
- Advanced usage — Running commands and services