"All you need on your local machine is Docker or Podman."
cderungenerates ephemeral containers for commands likenode,python, orgiton demand using container runtimes (Docker/Podman). It keeps your host clean and ensures reproducible environments defined in a single YAML file.
cderun supports four primary modes of operation:
Explicitly call cderun followed by the subcommand you want to run.
cderun [cderun-flags] <subcommand> [passthrough-args]Example:
cderun --tty node --versionCreate a symlink to cderun with the name of the tool you want to wrap.
cderun will automatically detect the tool name from the executable name.
ln -s cderun node
./node --version # Effectively runs 'cderun node --version'You can use cderun to run arbitrary commands in a containerized environment
by specifying the image. Since the first non-flag argument is always consumed
as a subcommand (lookup key), you must explicitly specify the entrypoint
if you want to execute a command that is not the default entrypoint of the image.
cderun --image=alpine --entrypoint=ls ls -lRun cderun with the --diagnosis flag to see system diagnostics
and available tools. This mode does not require a subcommand.
cderun --diagnosiscderun uses a strict boundary for argument parsing. The first non-flag argument is considered the subcommand. This subcommand acts as a lookup key for configuration.
- [cderun-flags]: Arguments before the subcommand are parsed as
cderunflags. - <subcommand>: The lookup key (e.g.,
node,python). It is NOT included in the final container command by default. - [passthrough-args]: All arguments after the subcommand are passed directly to the container.
The final command executed in the container consists of the passthrough-args.
cderun --tty docker --tty
| | | |
| | | +-- Passthrough argument (passed to docker)
| | +--------- Subcommand
| +--------------- cderun flag (TTY: true)
+---------------------- cderun command
Flags prefixed with --cderun- are "Internal Overrides" (P1). They have the highest priority in the resolution hierarchy (P1 > P2 CLI Flags > P3 Env Vars > P4 Tool Config > P5 Global Config > P6 Hardcoded Defaults).
In standard Wrapper Mode, these flags must be placed after the subcommand. cderun performs a "Hoisting" operation during preprocessing, moving these flags before the subcommand internally so they are parsed as cderun settings rather than being passed to the container.
# Standard Wrapper Mode: P1 flags go AFTER the subcommand
cderun node app.js --cderun-image node:20-alpine
# WRONG (will result in an error):
cderun --cderun-image node:20-alpine node app.jsHoisting ensures that cderun settings do not conflict with the flags of the tool you are wrapping.
- Detection:
cderunscans for the subcommand boundary. - Extraction: It gathers all
--cderun-prefixed flags (and their associated values) that appear after the subcommand. - Internal Relocation: These flags are moved before the subcommand internally before parsing begins.
This mechanism is especially critical in Symlink Mode (Polyglot Entry Point), where it allows you to configure cderun's behavior (e.g., node --cderun-tty) without affecting the arguments passed to the wrapped tool (e.g., node --version).
Note on Diagnosis Mode: In --diagnosis mode, since no subcommand boundary exists, P1 flags can be placed anywhere.
--tty,-t: Allocate a pseudo-TTY. (Default:false)--interactive,-i: Keep STDIN open even if not attached. (Default:false)--image: Container image to use.--entrypoint: Overwrite the default ENTRYPOINT of the image.--user,-u: Username or UID (format:<name|uid>[:<group|gid>]).--workdir,-w: Working directory inside the container.--env,-e: Set environment variables (KEY=VALUEorKEYfor host passthrough).--strict-env: Require all passed environment variables to be present on the host. (Default:false)--pull: Pull image before running (always,missing,never). (Default:missing)--pull-max-retries: Maximum number of retries for image pull. (Default:3)--pull-backoff-base: Base duration for exponential backoff during image pull (e.g.1s,500ms). (Default:1s)--remove: Automatically remove the container when it exits. (Default:true)--hang-timeout: Grace period after I/O completion before force-terminating the container (e.g.10s,5s,0for infinite). This applies to non-interactive or non-TTY sessions. (Default:10s)
--network: Connect a container to a network. (Default:bridge)--hostname: Container host name.--publish,-p: Publish a container's port(s) to the host.--publish-all,-P: Publish all exposed ports to random ports. (Default:false)--expose: Expose a port or a range of ports.--dns: Set custom DNS servers.--add-host: Add a custom host-to-IP mapping (host:ip).
--memory,-m: Memory limit (e.g.,512m,1g).--cpus: Number of CPUs (float).--device: Add a host device to the container.--privileged: Give extended privileges to this container. (Default:false)--cap-add: Add Linux capabilities.--cap-drop: Drop Linux capabilities.
--mount: Attach a filesystem mount (type=bind,source=...,target=...[,readonly][,optional]). Theoptionalparameter skips bind mounts if the source path is missing on the host.--mount-socket: Mount the container runtime socket into the container. (Default:false)--mount-cderun: Mount thecderunbinary into the container. (Enables--mount-socketautomatically)--mount-tools: Mount specified tools (comma-separated) defined in.tools.yamlinto the container.--mount-all-tools: Mount all tools defined in.tools.yamlinto the container.--socket-path: Path to the runtime socket on the host.--mount-socket-path: Path where the socket should be mounted inside the container.--mount-cderun-path: Host path to thecderunbinary to mount.
--config: Path tocderunconfig file (.cderun.yaml).--tool-config: Path to tools config file (.tools.yaml).--runtime: Container runtime to use (docker/podman).--dry-run: Preview container configuration without execution. (Requires a subcommand)--dry-run-format,-f: Output format for dry-run (yaml,json,simple).--diagnosis: Show system diagnostics and available tools. (No subcommand required)--diagnosis-format: Output format for diagnosis (yaml,json,simple).--log-level: Set log level (error,warn,info,debug,trace). (Default:warn)--log-format: Set log format (text,json).--log-timestamp: Include timestamp in logs. (Default:true)
(All flags have a corresponding --cderun- prefixed P1 override counterpart.)
cderun can be configured using environment variables. Almost all CLI flags have a corresponding CDERUN_ prefixed environment variable (e.g., CDERUN_IMAGE, CDERUN_TTY, CDERUN_REMOVE).
Key variables include:
CDERUN_IMAGE: Container image to use.CDERUN_CONFIG: Path to cderun config file.CDERUN_TOOL_CONFIG: Path to tools config file.CDERUN_RUNTIME: Container runtime to use (docker/podman).CDERUN_PULL_MAX_RETRIES: Maximum number of retries for image pull (default:3).CDERUN_PULL_BACKOFF_BASE: Base duration for exponential backoff during image pull (default:1s).CDERUN_HANG_TIMEOUT: Grace period for non-interactive or non-TTY sessions (default:10s).CDERUN_STRICT_ENV: If set totrue, requires all environment variables to be present on the host.CDERUN_DRY_RUN: If set totrue, enables dry-run mode.CDERUN_DRY_RUN_FORMAT: Output format for dry-run (yaml, json, simple).CDERUN_DIAGNOSIS: If set totrue, enables diagnosis mode.CDERUN_DIAGNOSIS_FORMAT: Output format for diagnosis (yaml, json, simple).CDERUN_PUBLISH_ALL: If set totrue, publish all exposed ports to random ports.CDERUN_LOG_LEVEL: Set log level (error, warn, info, debug, trace).CDERUN_LOG_FORMAT: Set log format (text, json).CDERUN_LOG_TIMESTAMP: Include timestamp in logs.
Note on List-type Options:
- CLI Flags (P1/P2): List-type flags must be repeated for each item.
- Example:
--env A=1 --env B=2
- Example:
- Environment Variables (P3): Use specific separators depending on the variable.
- Semicolon (
;):CDERUN_ENV,CDERUN_MOUNT - Comma (
,):CDERUN_MOUNT_TOOLS,CDERUN_DEVICE,CDERUN_PUBLISH,CDERUN_EXPOSE,CDERUN_DNS,CDERUN_ADD_HOST,CDERUN_CAP_ADD,CDERUN_CAP_DROP,CDERUN_ENTRYPOINT
- Semicolon (
cderun uses two configuration files to manage its behavior.
Used for general settings and defaults.
runtime: docker
defaults:
tty: true
interactive: true
remove: true
logging:
level: warn
format: textDefines how specific tools should be containerized.
node:
image: node:20-alpine
mounts:
- type: bind
source: .
target: /app
workdir: /app
python:
image: python:3.11-slimcderun supports both Docker and Podman. It can automatically detect
the available runtime by checking for common Unix socket paths.
- Strict boundary parsing separates
cderunflags from subcommand arguments. - Prevents flag conflicts between
cderunand wrapped commands. - Supports complex command structures with P1 internal overrides.
- Single binary can act as multiple tools via symlinks.
- Automatic tool detection from executable name.
- Seamless integration with existing workflows.
- Mount the
cderunbinary and other defined tools into the container. - Enables recursive container execution without installing tools in the container image.
- Transparently handles
cderunexecution inside acderun-managed container. - Automatically propagates host context and settings via snapshots.
- Reverse Path Resolution: Translates container-local paths back to host paths for nested mounts, ensuring the host-side Docker/Podman daemon can resolve volume sources.
- OverlayFS Detection: Automatically detects the root filesystem's
upperdirto map container files back to the host.
cderun protects your secrets. Environment variables containing sensitive keywords (like PASSWORD, SECRET, TOKEN, JWT) are automatically masked ([REDACTED]) in:
- Dry-run output (
--dry-run) - Debug logs (
--log-level debug)
The masking logic is intelligent and handles CamelCase (e.g., dbPassword) and different separators (e.g., API_KEY).
- Expressions: Use
{{HOME}},{{PWD}},{{BASE_HOME}},{{BASE_PWD}},{{file:name}}(limit 1MB),{{find_dir:name}},{{env:KEY}}, and{{env:KEY:-default}}in configuration files and CLI flags. - Tilde Expansion:
~and~/paths are expanded to the user's home directory. - Relative Path Handling: Intelligent absolute path resolution based on the origin of the setting (config file location vs. current directory).
- See Value Resolution for details.
Use {{file:.go-version}} or {{file:.nvmrc}} in your tool configuration to ensure the container image tag matches your project's version file:
# .tools.yaml
go:
image: "golang:{{file:.go-version}}"Use {{find_dir:.git}} to reference the project root regardless of your current working directory:
cderun --mount type=bind,source="{{find_dir:.git}}/logs",target=/logs my-toolTo run the unit tests:
make test
# or
go test ./...To run the End-to-End (E2E) tests which require a running Docker or Podman environment:
go test -tags=runtime ./...To generate a test coverage report:
make coverageThis project is under active development.