Search code examples
snakemakeapptainer

How to set apptainer shell when using --software-deployment-method apptainer with Snakemake?


For snakemake v8.10.8, if I have the following Snakefile that uses a container

rule hello_world_container:
    params:
        output_dir="results",
        name="standard model"
    output:
        "results/hello_world.txt"
    container:
        "docker://busybox:1.33"
    shell:
        """
        mkdir -p {params.output_dir}
        echo "Hello my Name is {params.name}" | tee {output}
        """

and so uses the --software-deployment-method apptainer command line option, how do I set the shell command that Apptainer will use at runtime? The shell defaults to Bash but there are containers that don't have bash as the shell, like busybox for example. So the following command for this Snakefile

snakemake --verbose --cores 1 --printshellcmds --software-deployment-method apptainer --snakefile Snakefile hello_world_container

fails immediately with

Command ' singularity  exec --home '<cwd>'  <cwd>/.snakemake/singularity/893d95b26cf7d03ff72563d5db3f40ca.simg bash -c 'set -euo pipefail;  
        mkdir -p results
        echo "Hello my Name is standard model" | tee results/hello_world.txt'' returned non-zero exit status 255.

Using the existing shell for using busybox with Apptainer works, as expected,

$ apptainer exec docker://busybox:1.33 sh -c "echo 'hello world'"
INFO:    Using cached SIF image
hello world

so how can the shell be set in Snakemake?


Solution

  • Currently, it is possible to set the shell for all rules using e.g.

    shell.executable("sh")
    

    somewhere before your first rule in the Snakefile. However, for your case, it would be better to be able to set the shell per rule. Technically, this is relatively easy to implement (although one has to modify some yet to be optimized code). I have done that now here: https://github.com/snakemake/snakemake/pull/2856