Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

26 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Caravan ๐Ÿช๐Ÿซ๐Ÿ›•

Make it easy to spin SLURM Cluster and submit your HPC workloads to it.

Caravan COver License Downloads GitHub stars

Pipeline

๐Ÿ› ๏ธ Build & Test ๐Ÿš€ Release

Release

GoReleaser Release

Install now

MacOS

  # Quick install
  go install github.com/hiteshsahu/caravan@latest
  
  # Edit your .zshrc:
  nano ~/.zshrc
  # Add this line:
  export PATH=$PATH:$HOME/go/bin
  # Save and reload:
  source ~/.zshrc

  caravan                   # Help
  caravan cluster up        # start SLURM
  caravan cluster status    # check status
  caravan submit workloads/submit_example.sh   # Submit JOBS
  
  # GPU Load: need real cuda GPU + Linux/WSL2  
  CARAVAN_GPU=real ./caravan submit workloads/gpu_example.sh

  caravan cluster down      # Tear down

Support Upto 1 GPU in c1 compute node to run workloads on common workstation with 1 GPU installed over PIC.

Can be extended to add more compute nodes for multi GPU setup

Tested on Windows + WSL2 + RTX 4060


Why Caravan

Developing Slurm workloads usually requires access to an HPC cluster. Slurm is powerful but a chore to operate and submit to.

Caravan makes it simple by bundling a complete Slurm cluster into a single CLI so you can develop, test and debug jobs locally.

It uses Docker or Podman behind the scenes and works with fake GPUs, making it ideal for CI, workshops and local development.

The cluster definition is embedded with //go:embed, so the binary is self-contained โ€” there's no separate cluster repo to clone. caravan cluster up extracts it and runs it via a docker/podman Engine.

Caravan uses Slurm โ€” it doesn't replace it. Slurm stays the scheduler;

Caravan is the control plane and easier developer experience around it.

flowchart LR
subgraph CaravanCLI["๐Ÿซ Caravan (CLI)"]
CLI["caravan<br/>cluster ยท submit ยท status"]
end

    CLI -->|"sbatch"| CTL
    CLI -->|"squeue ยท scontrol ยท sinfo"| CTL

    subgraph Slurm["Slurm Cluster<br/>Embedded, no accounting DB"]
        CTL["slurmctld ๐Ÿง <br/>Controller & Scheduler"]

        CTL --> N1["slurmd ๐Ÿ–ฅ๏ธ<br/>Compute Node"]
        CTL --> N2["slurmd ๐Ÿ–ฅ๏ธ<br/>Compute Node"]

        N1 --> S1["slurmstepd<br/>GPU Job"]
        N2 --> S2["slurmstepd<br/>GPU Job"]
    end

    N1 -. "DCGM / nvidia-smi" .-> OBS["๐Ÿฆ squint<br/>gpu-lens"]
    N2 -. "DCGM / nvidia-smi" .-> OBS

    classDef ctl fill:#EEEDFE,stroke:#534AB7,color:#26215C;
    classDef compute fill:#E1F5EE,stroke:#0F6E56,color:#04342C;
    classDef obs fill:#F1EFE8,stroke:#5F5E5A,color:#2C2C2A,stroke-dasharray:5 4;

    class CTL ctl;
    class N1,N2,S1,S2 compute;
    class OBS obs;
Loading

Its completing project to:

  • squint: TUI Dashboard to check workload & squatting GPUs
  • gpu-lens : Drop-in GPU + scheduler observability for clusters(SLURM+K8)

โšก Get Started

๐Ÿ“Ÿ Requires Go

Go Version

MacOS

brew install go

Windows

choco install golang

See Medium Post for more detail installing go on Windows

๐Ÿณ Container engine

Caravan can work with both Docker or Podman

  • it auto-detects (Docker first, thenPodman) and uses the matching Compose.
  • On Podman it uses podman-compose if installed, otherwise it will try to use podman compose.

You can Force Podman explicitly:

CARAVAN_ENGINE=podman caravan cluster up
CARAVAN_COMPOSE="podman compose" caravan cluster up

On macOS make sure the Podman VM is running first:

podman machine start

OS Support

Recommended Platform

Environment Recommendation
๐Ÿง Linux โญโญโญโญโญ Best for full development, testing, and production
๐ŸชŸ Windows + WSL2 โญโญโญโญโญ Best Windows experience, close to Linux
๐ŸŽ macOS โญโญโญโญ Great for UI and mock-mode development
๐ŸชŸ Native Windows โญโญโญ Good for CLI/UI development; use WSL2 for Linux tooling

Slurm + Caravan OS Compatibility

Feature Linux Windows + WSL2 Windows macOS
Build โœ… โœ… โœ… โœ…
Run mock mode โœ… โœ… โœ… โœ…
Live Slurm (squeue, sacct, scontrol) โœ… โœ… โš ๏ธ Slurm not Supported โš ๏ธ Slurm not Supported
DCGM GPU metrics โœ… โœ… โŒ โŒ
nvidia-smi GPU metrics โœ… โœ… โœ… โš ๏ธ Limited
Full end-to-end testing โœ… โš ๏ธ โŒ โŒ

Notes

  • Live Slurm support in WSL2 works if you have access to a remote Linux Slurm cluster (via SSH) or a local Slurm installation inside WSL2.
  • DCGM requires machine with NVIDIA GPU with CUDA support and the NVIDIA WSL driver stack.
  • nvidia-smi is only available on Windows and inside WSL2 when using the NVIDIA WSL GPU drivers.

Start Your Caravan ๐Ÿช๐Ÿซ

Install the CLI for as described in "Install Now" section

Once you have CLI ready, you can start cluster and submit jobs

Caravan Batch

โœจ 1. Using pre compile released Binary (for production)

Quick start with released CLI binary

On macOS

  
  caravan cluster up        # build + start (controller + 2 fake-GPU nodes)
  caravan cluster down      # stop (-v to also wipe volumes)
  caravan cluster status    # container state + sinfo
  caravan submit <script>   # stream a script into sbatch on the controller

Note:

  • The two compute nodes c1, c2 advertise gpu:4 each as fake, count-only GPUs
  • Real GPU scheduling, no hardware needed (no nvidia-smi telemetry) by default.

๐ŸŽฎ Using a real GPU

If you have an NVIDIA GPU with Docker GPU support enabled, opt in with

CARAVAN_GPU=real

  • c1 compute node gets the real GPU passed through (via NVIDIA Container Toolkit, no CUDA base image needed), while
  • c2 keeps the fake GPUs since most machines only have one physical GPU to give.

๐Ÿง On Linux / Windows (Git Bash)

  CARAVAN_GPU=real ./caravan cluster up
  CARAVAN_GPU=real ./caravan submit workloads/gpu_example.sh

โš™๏ธ 2. Build Locally (for devs)

If you prefer building CLI on your own you can build binary locally

Note: Replace caravan with ./caravan and you can use same commands for local CLI

๐Ÿ“ฆ On macOS

  # Build CLI locally
  go build -o caravan .
  ./caravan
  
  ./caravan cluster up        # build + start (controller + 2 fake-GPU nodes)
  ./caravan cluster down      # stop (-v to also wipe volumes)
  ./caravan cluster status    # container state + sinfo
  ./caravan submit <script>   # stream a script into sbatch on the controller

โŠž On Windows

Note: for PowerShell users: use ./caravan.exe instead of ./caravan.

   # Build CLI locally
   go build -o caravan.exe .
   ./caravan.exe --help
  
  ./caravan.exe cluster up        # build + start (controller + 2 fake-GPU nodes)
  ./caravan.exe cluster status    # container state + sinfo
  ./caravan.exe submit workloads/submit_example.sh
  ./caravan.exe cluster down      # stop (-v to also wipe volumes)

How it works

โ–ถ๏ธ Starting Slurm Cluster

Writes an embedded Slurm scaffold to

  • MacOS: ~/.caravan/cluster
  • Windows: %USERPROFILE%\.caravan\cluster

and runs docker/podman compose against it.

  ./caravan cluster up

You can override scafold to your desired directory by passing CARAVAN_DIR

  # override the scaffold location with `CARAVAN_DIR`
  CARAVAN_DIR=/tmp/caravan/cluster ./caravan cluster up

โŠž On Windows (PowerShell)

  $env:CARAVAN_GPU = "real"
  ./caravan.exe cluster up
  ./caravan.exe submit workloads/gpu_example.sh

Note

macOS isn't supported here. Docker Desktop for Mac has no GPU passthrough mechanism at all, and Macs don't have NVIDIA GPUs (Apple Silicon uses its own GPU; even older Intel MacBooks shipped AMD, not NVIDIA). Setting CARAVAN_GPU=real there fails c1 outright with something like "could not select device driver 'nvidia' with capabilities: [[gpu]]". Tested combination is an NVIDIA GPU + Docker Desktop on Windows/WSL2 or native Linux. The default fake-GPU cluster is unaffected and works the same everywhere.


๐Ÿ“‹ Checking Cluster Status

Print container state, then sinfo

  # check job status
  ./caravan cluster status
Output:
hitesh@Mac Caravan % ./caravan cluster status
CONTAINER ID  IMAGE                           COMMAND     CREATED         STATUS                 PORTS       NAMES
ce05d9f1bbd9  localhost/caravan-slurm:latest  slurmd      15 seconds ago  Up 1 second (healthy)              c1
0ef798e4b97c  localhost/caravan-slurm:latest  slurmd      15 seconds ago  Up 1 second (healthy)              c2
2f3e0982f69c  localhost/caravan-slurm:latest  slurmctld   14 seconds ago  Up 14 seconds                      slurmctld

PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
gpu*         up   infinite      2    unk c[1-2]
                            c2

Check logs slurmctld squeue

With Podman

  podman exec slurmctld squeue
Output:
hitesh@Mac Caravan %   podman exec slurmctld squeue
JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
1       gpu caravan-     root PD       0:00      1 (Nodes required for job are DOWN, DRAINED or reserved for jobs in higher priority partitions)

With Docker

  docker exec slurmctld squeue
  
  # download slurmctld logs
  docker exec slurmctld cat /var/log/slurm/slurmctld.log
  docker exec c1 cat /var/log/slurm/slurmd.log
Output:
[2026-06-27T19:31:38.456] Launching batch job 1 for UID 0
[2026-06-27T19:31:38.464] CPU frequency setting not configured for this node
[2026-06-27T19:31:38.573] [1.batch] done with step
[2026-06-27T19:36:33.488] Launching batch job 2 for UID 0
[2026-06-27T19:36:33.502] CPU frequency setting not configured for this node
[2026-06-27T19:36:33.700] [2.batch] done with step
[2026-06-27T19:38:48.497] Launching batch job 3 for UID 0
[2026-06-27T19:38:48.513] CPU frequency setting not configured for this node
[2026-06-27T19:38:48.725] [3.batch] done with step
[2026-06-27T19:39:18.499] Launching batch job 4 for UID 0
[2026-06-27T19:39:18.508] CPU frequency setting not configured for this node
[2026-06-27T19:39:18.609] [4.batch] done with step

๐Ÿ“ฅ Submitting a HPC Workload

Create a simple job script (see workloads/submit_example.sh) and submit it:

  # submit the example script
  ./caravan submit workloads/submit_example.sh
Output
โ†’ submitting workloads/submit_example.sh to local Slurm cluster in /Users/hitesh/.caravan/cluster
#!/usr/bin/env bash
#SBATCH --job-name=caravan-test
#SBATCH --output=caravan-test.out
#SBATCH --time=00:01:00
#SBATCH --ntasks=1

echo "Hello from Caravan job on $(hostname)"
sleep 5
echo "Done"

For a real GPU instead (see "Using a real GPU" above), submit workloads/gpu_example.sh the same way under CARAVAN_GPU=real: it requests --gres=gpu:1 and prints actual nvidia-smi output.


๐Ÿ’ฅ Tear Down Slurm Cluster

Tear down cluster and option to clean mounted volumes as well

  ./caravan cluster down      
  ./caravan cluster down  -v  # Also remove disc volumes  

๐Ÿ‘จโ€๐Ÿ’ป Development

โš™๏ธ Install dependencies

    # Install dependencies
    go mod tidy

๐Ÿงช Build & Test

Tests are run as part of CI itself.

   # Formatting go file
   gofmt -w . 
   
   # Linting
   go vet ./... 
   
   # recursively compiles all packages
   go build ./...   

โ–ถ๏ธ Run

    # Run the Engine
    go run .                 # mock
    

๐Ÿ“ Folder Structure

  caravan/
  โ”œโ”€โ”€ main.go
  โ”œโ”€โ”€ embed.go                 # go:embed slurm-cluster/* (must live next to it)
  โ”œโ”€โ”€ internal/
  โ”‚   โ”œโ”€โ”€ cli/                 # cobra commands
  โ”‚   โ”‚   โ”œโ”€โ”€ root.go
  โ”‚   โ”‚   โ”œโ”€โ”€ cluster.go       # caravan cluster up|down|status
  โ”‚   โ”‚   โ””โ”€โ”€ submit.go        # caravan submit <script.sh>
  โ”‚   โ””โ”€โ”€ cluster/
  โ”‚       โ”œโ”€โ”€ engine.go        # Engine interface + DockerEngine/PodmanEngine
  โ”‚       โ”œโ”€โ”€ compose.go       # compose file paths + CARAVAN_GPU gate
  โ”‚       โ”œโ”€โ”€ extract.go       # Scaffold (wired from embed.go) + extraction
  โ”‚       โ”œโ”€โ”€ status.go        # Up/Down/Status
  โ”‚       โ”œโ”€โ”€ submit.go        # Submit โ€” streams a script into sbatch
  โ”‚       โ””โ”€โ”€ util.go          # process-running helpers
  โ”œโ”€โ”€ slurm-cluster/           # the GPU Slurm cluster, embedded in the binary
  โ”‚   โ”œโ”€โ”€ Dockerfile ยท entrypoint.sh
  โ”‚   โ”œโ”€โ”€ docker-compose.yml ยท slurm.conf ยท gres.conf ยท cgroup.conf
  โ”‚   โ””โ”€โ”€ docker-compose.gpu.yml ยท slurm.gpu.conf ยท gres.gpu.conf  # CARAVAN_GPU=real overlay
  โ””โ”€โ”€ workloads/                # example job scripts
      โ”œโ”€โ”€ submit_example.sh
      โ”œโ”€โ”€ gpu_example.sh
      โ””โ”€โ”€ long_running_example.sh  # holds gpu:1 for 5 min โ€” good for watching squint live

๐Ÿ—บ๏ธ Roadmap

Caravan grows from "runs a cluster" to "runs your work on it."

  • cluster (here) โ€” up / down / status, behind a single Engine interface implemented by Docker and Podman today; cloud / bare-metal backends later.
  • submit (here) โ€” caravan submit script.sh streams the script straight into sbatch on the controller. logs to follow it; recording/rerun next.
  • rerun โ€” re-launch a past job by id, reproducibly.
  • exp โ€” group runs into experiments and compare them.

Each new capability sits behind a Backend interface (Slurm today), so swapping the execution target later doesn't touch the CLI above it.


License

ยฉ 2026 Hitesh Kumar Sahu ยท Licensed under Apache 2.0

About

A CLI for GPU Slurm - stand up a SLURM cluster in one command, built to run your workloads on it.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages