Basic Usage

Running a tool

kapsl [OPTIONS] [TOOL] [ARGS]...

Prepend kapsl to any tool name. kapsl looks up the image, pulls it if needed, and runs the tool in an ephemeral container with your current directory mounted at /kapsl/workdir.

kapsl jq --version
kapsl python --version
kapsl rg "TODO" .

The first run pulls the image. Subsequent runs use the local cache and start in milliseconds.

Pinning versions

Append @tag to use a specific image tag:

kapsl [email protected] --version
kapsl [email protected] --version
kapsl node@18 --version
kapsl node@22 --version

Security flags

By default, containers have no network access and the working directory is mounted read-only.

FlagEffect
--cap netAllow network access
--cap rwAllow writes to working directory
--cap roForce read-only working directory (overrides image defaults)
--cap nomountSkip mounting the working directory entirely — tighter than ro, for tools with no legitimate use for it
--privilegedDrop all capability restrictions
--cap rwimgAllow writes to the image filesystem
-p, --port <HOST:CONTAINER>Publish a container port to the host (implies --cap net)

See CLI Reference for the complete flag list, including the browser/clipboard relays and scan controls.

kapsl --cap net curl https://example.com
kapsl --cap rw python -c "open('out.txt', 'w').write('done')"

Platform and runtime

kapsl --platform linux/amd64 python --version
kapsl --runtime docker python --version      # force Docker over Podman

Installing shims

For tools you use frequently, create a shim so you can skip the kapsl prefix:

kapsl --install rg
rg "TODO" .    # same as: kapsl rg "TODO" .

Shims are symlinks at ~/.local/bin/<tool>kapsl. kapsl reads argv[0] to determine the tool name.

Listing shims

kapsl --list

Searching the tool index

kapsl --search dns
kapsl --search python
kapsl --search kubernetes

Search matches tool names, descriptions, and tags.

Environment files

Install packages before running a tool using -e:

kapsl -e @pip:requirements.txt python script.py
kapsl -e @npm:package.json node app.js

See Environments for details.

CI mode

In CI, pass --non-interactive (or set the CI environment variable) to disable TTY allocation:

kapsl --non-interactive python -c "import sys; print(sys.version)"

kapsl auto-detects CI=true and disables TTY automatically.

Reclaiming disk

kapsl --status    # what kapsl is storing, by category
kapsl --clean     # leaked scan scratch + kapsl-env-* environment images

Bare kapsl --clean removes only what costs nothing to recreate: leaked per-run scan scratch, and container images kapsl built for environment builds (named kapsl-env-*). Base images are never affected.

Pass a target to go further — kapsl --clean cache drops every regenerable cache including the vulnerability database, and asks first. See the commands reference for the full target list, --dry-run, and what --clean refuses to remove.

Kubernetes

Run a tool as a temporary pod in your current cluster context:

kapsl --k8s python --version
kapsl --k8s --namespace staging python script.py
kapsl --k8s --node worker-1 htop

See Kubernetes for more.

Common patterns

# Process stdin
echo '{"x":1}' | kapsl jq '.x'

# Use a requirements file
kapsl -e @pip:requirements.txt [email protected] script.py

# Network access for downloads
kapsl --cap net python -c "import urllib.request; urllib.request.urlretrieve('https://example.com/file', 'file')"

# Portable shebang scripts
chmod +x script.py   # script starts with: #!/usr/bin/env -S kapsl [email protected]:requests
./script.py