Container Platforms
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:
| Component | Purpose | Example |
|---|---|---|
| Path | Executable or wrapper command | docker, orb, limactl, wsl |
| Args | Arguments prepended to every invocation | ["--context", "orbstack"] |
| Registry | Default registry URL for login | docker.io, docker://docker.io |
Defaults per platform (*-args default to []):
| Platform | Path | Registry | Env Prefix |
|---|---|---|---|
| Docker | docker | docker.io | DOCKER_* |
| Podman | podman | docker.io | PODMAN_* |
| Singularity | singularity | docker://docker.io | SINGULARITY_* |
| Apptainer | apptainer | docker://docker.io | APPTAINER_* |
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 singularity ↔ apptainer 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"]
Install
More VM control (mounts, resources). Each command wraps as limactl shell <vm> <runtime>.
brew install lima
limactl start --name=dxflow --tty=false template://ubuntu
limactl shell dxflow sudo apt-get install -y docker.io podman apptainer
limactl shell dxflow sudo usermod -aG docker "$USER"
Configure
Add the wrappers to ~/.dxflow/default_config.yaml:
docker-path: limactl
docker-args: ["shell", "dxflow", "sudo", "docker"]
podman-path: limactl
podman-args: ["shell", "dxflow", "podman"]
singularity-path: limactl
singularity-args: ["shell", "dxflow", "apptainer"]
apptainer-path: limactl
apptainer-args: ["shell", "dxflow", "apptainer"]
Install
Install the runtimes inside a WSL distro; each command wraps as wsl -d <distro> <runtime>.
wsl --install -d Ubuntu
wsl -d Ubuntu sudo apt-get install -y docker.io podman apptainer
wsl -d Ubuntu sudo usermod -aG docker "$USER"
Configure
Add the wrappers to %USERPROFILE%\.dxflow\default_config.yaml:
docker-path: wsl
docker-args: ["-d", "Ubuntu", "sudo", "docker"]
podman-path: wsl
podman-args: ["-d", "Ubuntu", "podman"]
singularity-path: wsl
singularity-args: ["-d", "Ubuntu", "apptainer"]
apptainer-path: wsl
apptainer-args: ["-d", "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
| Concept | Docker / Podman | Singularity / Apptainer |
|---|---|---|
| Running unit | Container | Instance |
| Image format | OCI layers | SIF file |
| Image storage | Registry | File system |
| Image pull prefix | alpine:latest | docker://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.