Advanced Topics

Container Platforms

Configure Docker, Podman, Singularity, and Apptainer, including running them through a VM wrapper (OrbStack, Lima, WSL) on macOS and Windows

dxflow drives four container runtimes — Docker, Podman, Singularity, and Apptainer — behind one unified API. The same operations (login, image pull, run, stop) work across all four: Docker/Podman manage containers; Singularity/Apptainer manage instances from SIF images. Each runtime can run natively on the host or inside a Linux VM reached through a wrapper.

Configuration model

Each platform takes three values, set in the active profile (~/.dxflow/<profile>_config.yaml) or via environment variables:

ComponentPurposeExample
PathExecutable or wrapper commanddocker, orb, limactl, wsl
ArgsArguments prepended to every invocation["--context", "orbstack"]
RegistryDefault registry URL for logindocker.io, docker://docker.io

Defaults per platform (*-args default to []):

PlatformPathRegistryEnv Prefix
Dockerdockerdocker.ioDOCKER_*
Podmanpodmandocker.ioPODMAN_*
Singularitysingularitydocker://docker.ioSINGULARITY_*
Apptainerapptainerdocker://docker.ioAPPTAINER_*

Command construction

Commands are built as {path} {args...} {subcommand} {subcommand-args...}:

# Config
docker-path: docker
docker-args: ["--context", "orbstack"]

# Result
docker --context orbstack image pull alpine

This is what lets a platform point at a wrapper (orb, limactl, wsl) that reaches a runtime inside a Linux VM.

Running through a VM (macOS & Windows)

There is no native runtime on macOS or Windows: the engine runs natively, but containers run inside a Linux VM. Point each platform path at a wrapper that forwards commands into the VM. Docker needs sudo (root-owned daemon); Podman, Singularity, and Apptainer are rootless.

Install

Docker runs through the orbstack context; the others run in an OrbStack Linux machine reached with orb -m <machine>.

brew install orbstack
orb create ubuntu                                   # Linux machine named "ubuntu"
orb -m ubuntu sudo apt-get install -y podman apptainer

Configure

Add the wrappers to ~/.dxflow/default_config.yaml (swap singularityapptainer freely):

docker-args: ["--context", "orbstack"]
podman-path: orb
podman-args: ["-m", "ubuntu", "podman"]
singularity-path: orb
singularity-args: ["-m", "ubuntu", "apptainer"]
apptainer-path: orb
apptainer-args: ["-m", "ubuntu", "apptainer"]

Verify the configuration

Boot at debug level — the engine logs the resolved command for every platform as it loads, so you can confirm a wrapper is applied before any container command runs:

dxflow --log-level debug boot up --http
DBG Loaded docker platform config path=limactl args=["shell","dxflow","sudo","docker"]
DBG Loaded podman platform config path=limactl args=["shell","dxflow","podman"]
DBG Loaded singularity platform config path=limactl args=["shell","dxflow","apptainer"]
DBG Loaded apptainer platform config path=limactl args=["shell","dxflow","apptainer"]

Read back a single value any time with dxflow config get docker-path (or docker-args, podman-path, …).

Platform differences

ConceptDocker / PodmanSingularity / Apptainer
Running unitContainerInstance
Image formatOCI layersSIF file
Image storageRegistryFile system
Image pull prefixalpine:latestdocker://alpine:latest
GPU flag--gpus all--nv (NVIDIA) / --rocm (AMD)

For the full list of platform endpoints (login, image, container/instance lifecycle), see the Platform API.