Skip to content
Docs

Strict Environments

By default, activate prepends the crate’s shimlink directory to your PATH, overlaying crate commands on top of the current environment. Crate commands take priority, but all your usual host commands (grep, ls, cat, etc.) remain available. This is convenient for interactive work.

Strict mode replaces your PATH entirely — only commands defined in the crate are available. This gives you a controlled, reproducible environment where you know exactly which tools are in scope.

# Normal: crate commands + host commands
bulker activate demo
# Strict: crate commands only
bulker activate -s demo
  1. Replaces PATH instead of prepending to it. Your PATH becomes just the shimlink directory (a unique temp directory created per activation), so external binaries not in the crate can’t be found.
  2. Skips your shell config — your .bashrc / .zshrc is not sourced, so aliases, functions, and shell customizations don’t carry over.

Strict mode controls what’s on PATH, but it can’t block shell builtins. Commands like echo, cd, export, printf, type, and test are handled internally by bash/zsh and don’t require PATH lookup. These will always work regardless of strict mode.

If a command works in strict mode but isn’t in your crate, it’s probably a builtin. You can check with type <command> (itself a builtin).

Bulker stores the absolute path to your container engine (e.g., /usr/bin/docker) in the config’s engine_path field, auto-detected on first use. All container dispatch — shimlink execution, image pulls, and template rendering — uses this absolute path, so the container engine works in strict mode even when it’s not on PATH.

If your config was created before this feature existed and is missing engine_path, run bulker config init --force to regenerate it, or manually add engine_path: /usr/bin/docker to your config. Without engine_path, bulker falls back to looking up the engine name via PATH.

Replacing PATH removes all external executables. While the container engine itself is handled automatically via engine_path, you may still want other host utilities available. List them under host_commands in your manifest:

manifest:
name: alpine
commands: null
description: A set of host commands useful in strict mode.
host_commands:
- id
- ls
- lesspipe
- dircolors
- basename
- dirname
- which

Unlike regular commands (which create shimlinks to the bulker binary for container dispatch), host_commands create symlinks directly to the host binaries. This makes them available in the shimlink directory without routing through Docker.

For a minimal strict environment, your manifest works as-is — the container engine is resolved automatically. If you need host utilities like ls, which, or id, import the alpine manifest:

manifest:
name: my-tools
imports:
- bulker/alpine
commands:
- command: samtools
docker_image: quay.io/biocontainers/samtools:1.9--h91753b0_8

Without this import, you’ll have access to your crate’s containerized commands but not host utilities like ls and which. Bulker prints a note when activating in strict mode with no host commands, as a reminder.

See Import Crates for more on imports.

For one-off commands, exec also supports the -s flag:

bulker exec -s demo -- fortune

This runs the command in a strict environment without entering an interactive shell.

By default, bulker passes all host environment variables into containers. This mirrors how native commands work — your LANG, DISPLAY, EDITOR, and other env vars are available inside the container.

For reproducible or isolated environments, use --strict-env to start containers with a clean environment. Only variables listed in the envvars config key and per-command envvars in the manifest are passed through:

# Clean environment: only allowlisted env vars
bulker activate --strict-env demo
# One-off with clean environment
bulker exec --strict-env demo -- samtools --version
# Combine both: strict PATH + strict env
bulker activate -s --strict-env demo

-s (strict) and --strict-env are independent and can be combined:

PATH commandsEnvironment variables
NormalAll host commands + crate commandsAll host env vars passed
-sOnly crate + host_commandsAll host env vars passed
--strict-envAll host commands + crate commandsOnly envvars allowlist
-s --strict-envOnly crate + host_commandsOnly envvars allowlist
  • Docker: In normal mode, every host env var (except PATH, HOME, HOSTNAME, and bulker internals) is passed via --env. In --strict-env mode, only the allowlisted vars get --env flags.
  • Apptainer: Apptainer inherits the host environment by default. In --strict-env mode, bulker adds --cleanenv to start clean, then passes each allowlisted var via --env NAME=VALUE.

The allowlist used by --strict-env merges three sources:

  1. Config-level envvars — apply to every container (default: [DISPLAY])
  2. Per-command envvars — listed in the manifest envvars field
  3. BULKER_EXTRA_ENVVARS — runtime additions via environment variable

In normal mode (without --strict-env), these fields are ignored since all host env vars are passed anyway.

See Volumes and Environment Variables for details on configuring the allowlist.