Apptainer on chip (via Slurm)

Apptainer on chip (via Slurm)

This page provides a step-by-step walkthrough for running Apptainer containers on the chip cluster, using the Slurm workload manager. It includes real-world usage tips, working examples, and solutions to common problems.


What is Apptainer?

srun

Apptainer is a container platform designed for high-performance computing (HPC) environments. It allows users to create and run a containerized application in a secure, reproducible, and portable way- without requiring root privileges.

Key features:

  • Runs containers securely in multi-user HPC clusters

  • Enables reproducible scientific workflows

  • Supports building and running containers from Docker and OCI images

  • Integrates well with job schedulers like Slurm

Unlike Docker, which requires daemon access and elevated privileges, Apptainer is purpose-built for HPC systems, making it ideal for use on clusters like chip!

For any general inquiries regarding Apptainer, please consult the official Apptainer_Documentation.


Prerequisites

  1. chip Account- You must have a valid chip account.

  2. Compute Node Access- Apptainer must be run on a compute node.

  3. Basic Linux Knowledge- Familiarity with command-line tools and basic Linux commands is helpful but not required.

    • While you can follow this guide without prior experience, knowing basic commands will make troubleshooting and navigation easier.


1. Log into chip and Start an Interactive Job on a Compute Node

[username@chip ~]$ srun --cluster=chip-cpu --account=pi_doit --partition=general --qos=normal --time=00:10:00 --mem=100 --pty $SHELL [username@c21-06 ~]$

Note: Our interactive job has been successfully initiated on a compute node (c21-06). We currently have 10 minutes and 100MB of memory allocated for this task. This is sufficient for testing a lightweight container in the following steps.


2. Load Required Modules

Before loading Apptainer, you can check available versions:

[username@chip ~]$ module avail apptainer ------------------------------------------ Core & Custom Modules ------------------------------------------- apptainer/1.3.5 apptainer/1.4.0-rc.2 (D) Where: D: Default Module Module defaults are chosen based on Find First Rules due to Name/Version/Version modules found in the module tree.

Then load the required modules:

[username@c21-06 ~]$ module load shared The following have been reloaded with a version change: 1) Slurm/chip-gpu/23.11.4 => Slurm/chip-cpu/23.11.4 [username@c1-06 ~]$ module load apptainer/1.4.0-rc.2

Tip: Always confirm the version you load is compatible with your workflow. Using module avail helps ensure you select a version supported on the cluster.


3. Create a Definition File

A definition file (.def) tells Apptainer how to build your container, including:

  • The base image to start from.

  • The package to install.

  • Any setup commands to run inside the container during the build process.

Here’s how to create one on chip:

  1. Ensure you are on a compute node (see Step 1).

  2. Use a text editor like nano or vim to create a new file:

[username@c1-06 ~]$ vim test.def
  1. Add the following content to your file:

Bootstrap: docker From: ubuntu:24.04 %post apt-get update && apt-get install -y cowsay lolcat %environment export LC_ALL=C export PATH=/usr/games:$PATH %runscript date | cowsay | lolcat

Note: To edit in vim press i (insert) and to save your changes press esc -> : -> wq -> Enter .(write and quit out of your file).


4. Build the Container from that file:

[username@c1-06 ~]$ apptainer build test.sif test.def
  • test.sif -> Output container image file.

  • test.def -> Definition file created in Step 3.

Tip: Thats it - There’s no need to pre-create folders, special configs, or run any prep commands. Apptainer will take the .def file, pull the base image, and run your %post instructions inside it during the build.

What Happens During the Build

  1. Pulls the base image (ubuntu:24.04) from Docker Hub.

  2. Creates a writeable build environment.

  3. Runs our %post commands inside the container (e.g., installing cowsay and lolcat).

  4. Packages everything into a .sif file (portable, read-only container).

Example Successful Output

[username@c1-06 ~]$ apptainer build test.sif test.def .... done. INFO: Adding environment to container INFO: Adding runscript INFO: Creating SIF file... INFO: Build complete: test.sif

5. Run the Container

To run the container and execute the default %runscript (in our case, the date piped through cowsay and lolcat):

[username@c1-06 ~]$ apptainer run test.sif

Expected output will be something like:

______________________________ < Fri Aug 22 14:13:56 EDT 2025 > ------------------------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||

(with rainbow coloring from lolcat)


6. Run Commands Inside the Container

By Default, apptainer run will execute the container’s runscript. But if you want to run a scpecific command instead, you can use exec.

For example:

[username@c1-06 ~]$ apptainer exec test.sif cowsay "Hello from inside Apptainer" _____________________________ < Hello from inside Apptainer > ----------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
  • Here, Apptainer starts the container environment, runs cowsay inside it, then exits.

Key Point: exec lets you run any command available in the container, instead of being limited to the default runscript. This is especially useful for testing, debugging, or running one-off commands like python, ls, or bash.


7. Submit a Container Job with Slurm

Running interactively is useful for testing but let's also see how this can be done through a batch job. You can submit jobs that run inside containers just like you would with normal Slurm jobs.

Create a file called apptainer_job.sbatch

[username@c1-06 ~]$ vim apptainer_job.sbatch
#!/bin/bash #SBATCH --job-name=apptainer_demo #SBATCH --output=Slurm-%j.out #SBATCH --time=00:05:00 #SBATCH --mem=200 #SBATCH --partition=general module load apptainer/1.4.0-rc.2 apptainer exec test.sif cowsay "Hello from Slurm + Apptainer"

Submit with:

[username@c1-06 ~]$ sbatch apptainer_job.sbatch Submitted batch job 336687

When the job finishes, check the output in Slurm-<jobid>.out

[username@c1-06 ~]$ cat Slurm-336687.out ______________________________ < Hello from Slurm + Apptainer > ------------------------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||

8. Troubleshooting

Modules do not function on the login nodes

[username@chip ~]$ module load apptainer Note: Modules do not function on the login nodes

Cause: You are trying to load modules from the login node, but on chip all modules (including Apptainer) can only be loaded from a compute node.

Fix: First start an interactive job, then load the module inside that session:

[username@chip ~]$ srun --cluster=chip-cpu --account=pi_doit --partition=general --qos=normal --time=00:10:00 --mem=100 --pty $SHELL [username@c1-06 ~]$ module load shared The following have been reloaded with a version change: 1) Slurm/chip-gpu/23.11.4 => Slurm/chip-cpu/23.11.4 [username@c1-06 ~]$ module load apptainer/1.4.0-rc.2

“apptainer: command not found”

[username@c1-06 ~]$ apptainer --version bash: apptainer: command not found

Cause: The Apptainer module isn’t loaded in this session.

Fix: Load the required modules:

[username@c1-06 ~]$ module load shared The following have been reloaded with a version change: 1) Slurm/chip-gpu/23.11.4 => Slurm/chip-cpu/23.11.4 [username@c1-06 ~]$ module load apptainer/1.4.0-rc.2

Job finishes but Slurm-<jobid>.out is empty

[username@c1-06 ~]$ vim apptainer_job.sbatch
#!/bin/bash #SBATCH --job-name=apptainer_demo #SBATCH --output=Slurm-%j.out #SBATCH --time=00:05:00 #SBATCH --mem=200 #SBATCH --partition=general module load apptainer/1.4.0-rc.2 # This is command succeeds but prints nothing true
[username@c1-06 ~]$ sbatch apptainer_job.sbatch Submitted batch job 336687 [hfessuh1@c1-06 ~]$ cat Slurm-336687.out [hfessuh1@c1-06 ~]$

Cause: No command writes to stdout → output file is empty.

Fix: Update the sbatch file to include a command that outputs something