dstack is an open-source control plane for GPU provisioning and orchestration across GPU clouds, Kubernetes, and on-prem clusters.
dstack provisions and orchestrates workloads across GPU clouds, Kubernetes, and on-prem via fleets.
When to use this skill:
*.dstack.yml configurationsdstack operates through three core components:
dstack server - Can run locally, remotely, or via dstack Sky (managed)dstack CLI - Applies configurations and manages resources; the CLI can be pointed to a server and default project (~/.dstack/config.yml or via dstack project)dstack configuration files - YAML files ending with .dstack.ymldstack apply plans, provisions cloud resources, and schedules containers/runners. By default it attaches when the run reaches running (opens SSH tunnel, forwards ports, streams logs). With , it submits and exits.
-decho "n" | dstack apply -f <config>dstack apply -f <config> -y -ddstack ps -vdstack attach locally and share the outputCRITICAL: Never propose dstack CLI commands or YAML syntaxes that don't exist.
--help--helpNEVER do the following:
--helpdstack apply for runs without -d in automated contexts (blocks indefinitely)echo "y" | when -y flag is availabledstack <command> --help first.dstack --help # List all commands
dstack apply --help <configuration type> # Flags for apply per configuration type (dev-environment, task, service, fleet, etc)
dstack fleet --help # Fleet subcommands
dstack ps --help # Flags for ps
Commands that stream indefinitely in the foreground:
dstack attachdstack apply without -d for runsdstack ps -wAgents should avoid blocking: use -d, timeouts, or background attach. When attach is needed, run it in the background by default (nohup ...), but describe it to the user simply as "attach" unless they ask for a live foreground session. Prefer dstack ps -v and poll in a loop if the user wants to watch status.
All other commands: Use 10-60s timeout. Most complete within this range. While waiting, monitor the output - it may contain errors, warnings, or prompts requiring attention.
Confirmation handling:
dstack apply, dstack stop, dstack fleet delete require confirmation-y flag to auto-confirm when user has already approveddstack stop, always use -y after the user confirms to avoid interactive promptsecho "n" | to preview dstack apply plan without executing (avoid echo "y" |, prefer -y)Best practices:
dstack apply (unless it's an exception)-y flag to skip confirmation prompts-d)After submitting a run with -d (dev-environment, task, service), first determine whether submission failed. If the apply output shows errors (validation, no offers, etc.), stop and surface the error.
If the run was submitted, do a quick status check with dstack ps -v, then guide the user through relevant next steps:
If you need to prompt for next actions, be explicit about the dstack step and command (avoid vague questions). When speaking to the user, refer to the action as "attach" (not "background attach").
dstack ps -v every 10-20s if the user wants updates.running, attach to surface the IDE link/port forwarding/SSH alias, then ask whether to open the IDE link. Never open links without explicit approval.dstack logs for progress; attach only if full log replay is required.dstack attach runs until interrupted and blocks the terminal. Agents must avoid indefinite blocking. If a brief attach is needed, use a timeout to capture initial output (IDE link, SSH alias) and then detach.
Note: dstack attach writes SSH alias info under ~/.dstack/ssh/config (and may update ~/.ssh/config) to enable ssh <run name>, IDE connections, port forwarding, and real-time logs (dstack attach --logs). If the sandbox cannot write there, the alias will not be created.
Permissions guardrail: If dstack attach fails due to sandbox permissions, request permission escalation to run it outside the sandbox. If escalation isn’t approved or attach still fails, ask the user to run dstack attach locally and share the IDE link/SSH alias output.
Background attach (non-blocking default for agents):
nohup dstack attach <run name> --logs > /tmp/<run name>.attach.log 2>&1 & echo $! > /tmp/<run name>.attach.pid
Then read the output:
tail -n 50 /tmp/<run name>.attach.log
Offer live follow only if asked:
tail -f /tmp/<run name>.attach.log
Stop the background attach (preferred):
kill "$(cat /tmp/<run name>.attach.pid)"
If the PID file is missing, fall back to a specific match (avoid killing all attaches):
pkill -f "dstack attach <run name>"
Why this helps: it keeps the attach session alive (including port forwarding) while the agent remains usable. IDE links and SSH instructions appear in the log file -- surface them and ask whether to open the link (open "<link>" on macOS, xdg-open "<link>" on Linux) only after explicit approval.
If background attach fails in the sandbox (permissions writing ~/.dstack or ~/.ssh, timeouts), request escalation to run attach outside the sandbox. If not approved, ask the user to run attach locally and share the IDE link/SSH alias.
"Run something": When the user asks to run a workload (dev environment, task, service), use dstack apply with the appropriate configuration. Note: dstack run only supports dstack run get --json for retrieving run details -- it cannot start workloads.
"Connect to" or "open" a dev environment: If a dev environment is already running, use dstack attach <run name> --logs (agent runs it in the background by default) to surface the IDE URL (cursor://, vscode://, etc.) and SSH alias. If sandboxed attach fails, request escalation or ask the user to run attach locally and share the link.
dstack supports five main configuration types. Configuration files can be named <name>.dstack.yml or simply .dstack.yml.
Common parameters: All run configurations (dev environments, tasks, services) support many parameters including:
repo), mount existing repos (repos)files (see concept docs for examples)image); use docker: true if you want to use Docker from inside the container (VM-based backends only)env), often via .envrc. Secrets are supported but less common.volumes), specify disk sizeBest practices:
name property for easier managementenv section (e.g., - HF_TOKEN), not values. Recommend storing actual values in a .envrc file alongside the configuration, applied via source .envrc && dstack apply.python and image are mutually exclusive in run configurations. If image is set, do not set python.files and repos intent policyUse files and repos only when the user intends to use local/repo files inside the run.
files or repos as appropriate.files guidance:
files path is placed under the run's working_dir (default or set by user).repos + image/working directory guidance:
repos (e.g., .:/dstack/run).working_dir to the same path.dstack default images, the default working_dir is already /dstack/run.When resources.gpu targets AMD (e.g., MI300X), you have to set image.
Use the official ROCm Docker image namespace as the default source: https://hub.docker.com/u/rocm
rocm/* framework images and select tags with the latest available ROCm version by default. Pick the most recent ROCm-compatible tag appropriate for the requested AMD GPU family.
rocm/sgl-devrocm/vllmrocm/pytorchrocm/dev-ubuntu-24.04.Additional guidance:
:latest where applicable for generic/default recommendations, unless the user asks for pinning or reproducibility.Use for: Interactive development with IDE integration (VS Code, Cursor, etc.).