Demo: build a container (apptainer SIF) and run it on the inslurm Slurm cluster via the inslurm_runner Forgejo Actions runner.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
marmaduke woodman e4274afa1e
All checks were successful
inslurm-runner-demo / build-and-run-on-inslurm (push) Successful in 5s
README: fix template notes + workspace shared-home clarification
2026-09-16 11:03:23 +02:00
.forgejo/workflows Fix container: python:3.12-alpine base (alpine had no python3); pin srun cpus 2026-09-16 11:00:32 +02:00
app Demo: build container (apptainer SIF) and run it on inslurm via srun 2026-09-16 10:39:17 +02:00
apptainer.def Fix container: python:3.12-alpine base (alpine had no python3); pin srun cpus 2026-09-16 11:00:32 +02:00
README.md README: fix template notes + workspace shared-home clarification 2026-09-16 11:03:23 +02:00

it/inslurm-runner-demo

A ready-to-copy template for running containerized jobs on the inslurm Slurm cluster from Forgejo Actions, using the dedicated inslurm_runner host runner.

It demonstrates the two things this cluster needs, because inslurm has no docker:

  1. Build a container — as an Apptainer SIF built from a .def recipe on the Forgejo host (unprivileged, no docker).
  2. Run it on a compute node — the heavy step is dispatched with srun to a real Slurm node, and the SIF is executed there with apptainer run.

What each file does

file purpose
.forgejo/workflows/demo.yml The CI workflow: build the SIF, then srun it onto a compute node and run it.
apptainer.def The container recipe (base python:3.12-alpine + the small demo.py payload).
app/demo.py The code that runs inside the container.

How to use it as a template

  • Manual copy (simplest): clone it and re-push to your own repo. Update the repo name / SIF name in demo.yml comments if you prefer.

  • Forgejo template: this repo can be marked as a template (Settings → Repository → Template) so forks can "Use this template".

The workflow targets the inslurm runner, so any repo whose jobs use runs-on: inslurm will be picked up by inslurm_runner (a global, all-repos runner on git.ins-amu.fr).

How the workflow works

graph LR
    A[push] --> B[build SIF on head]
    B --> C[stage SIF in shared home]
    C --> D[srun to compute node]
    D --> E[apptainer run inside SIF]
    E --> F[sacct? not needed - check log]
  1. runs-on: inslurm — selects inslurm_runner (host executor on the head node).
  2. Buildapptainer build app.sif apptainer.def builds the container on the head as the runner user. The ~/.cache and the SIF land in the shared home, which every compute node mounts at the same absolute path.
  3. Dispatch — the run step invokes srun --chdir=<shared home> apptainer run app.sif. Slurm places it on a free compute node (queuing automatically if none is free), and the container executes there.

Notes & limits (read before adapting)

  • The host runner is a job body, not a scheduler. Workload actually done on compute nodes is whatever you put inside srun/sbatch. inslurm_runner.capacity is 4, so up to 4 CI jobs run concurrently on the head; Slurm itself schedules the srun work.
  • Slurm has AuthType=auth/none and no slurmdbd, so there is no per-user accounting; submission is gated by AD group membership (inslurm_users). sacct will report "accounting disabled" — read job results from the workflow log instead.
  • Build on the head, run on the node. The workspace is under ~/.cache/act beneath the shared home, which every compute node mounts at the same path — so the built app.sif (and the checked-out repo) are visible from the compute node at $PWD. That's why the workflow dispatches srun --chdir="$PWD". Anything you stage outside the shared home is NOT visible to nodes; use a shared mount.
  • GPU jobs need --gres=gpu:1 (and pin a g-node) in the srun line, plus apptainer run --nv to bind the driver. See the apptainer-contained-builds skill.
  • Kerberos/shared mounts (/mnt/data CIFS etc.) work because inslurm_runner has a keytab + hourly kinit — see cluster-kerberos-tickets.

Files

.
├── .forgejo/workflows/demo.yml
├── app
│   └── demo.py
├── apptainer.def
└── README.md