Switch between Docker and Apptainer#

Goal#

Choose whether PlayMolecule executes app containers with Docker or Apptainer.

Minimal example#

export PM_RUNTIME=docker      # default
# or
export PM_RUNTIME=apptainer

The setting takes effect on the next import playmolecule.

When to use which#

Runtime

Choose when

docker

You’re on a workstation or VM. Your user can docker run without sudo.

apptainer

You’re on a shared HPC node where the cluster policy forbids Docker, or you can’t get root help to add yourself to the docker group.

For SLURM workers, Apptainer is almost always the only viable choice.

What changes under the hood#

  • docker — PlayMolecule shells out to the docker CLI, pulling images from the registry into the daemon’s image store. Containers are launched with docker run.

  • apptainer — PlayMolecule converts each Docker image into a plain SIF file once (via apptainer pull docker://..., cached under PM_SIF_CACHE_DIR, default ~/.cache/playmolecule/apptainer/), then runs apptainer run against the SIF.

The image content is identical; the runtime and packaging differ.

Apptainer prerequisites#

You need a working apptainer. On modern kernels with user namespaces enabled, that’s all — Apptainer runs unprivileged. On older or hardened kernels you may also need the apptainer-suid package, which provides a setuid helper as a fallback.

apptainer --version

Official install instructions: https://apptainer.org/docs/admin/main/installation.html.

Custom SIF cache location#

export PM_SIF_CACHE_DIR=/scratch/$USER/playmolecule-sif

Move the cache off $HOME if you’re running on a node with a tiny home quota — SIF files for the larger ML apps can be several GB.

On a multi-node cluster, point PM_SIF_CACHE_DIR at a path on shared storage (e.g., /shared/playmolecule/apptainer/). The first worker to need an image converts it from Docker once; every subsequent worker — and every other user — reads the same SIF directly. Without a shared cache, every node pulls a fresh copy on first use, which can mean tens of GB of redundant network traffic per app rollout.

Extracting an artifact in Apptainer mode#

Use app artifacts works in either runtime. With Apptainer, artifact.download() shells out to apptainer exec against the cached SIF; the SIF must exist locally first (it’s created automatically the first time you call the app).

Gotchas#

  • The two runtimes don’t share an image cache. Switching mid-workflow re-downloads everything once.

  • If apptainer pull docker://... fails on a hardened node, the kernel may not support user namespaces. Either enable them or install the apptainer-suid package as a fallback. PlayMolecule itself never calls sudo.

  • docker mode requires the daemon to be running and the user to be in the docker group (or to have sudo without password).

See also#