CLI & API¶
The primary way to use dstack is the CLI. It can be used to manage
fleets, runs, volumes, and
gateways, view logs, and inspect
events. Use the HTTP API for functionality not
available in the CLI or for integrations that need to call the server directly.
CLI¶
See installation on how to install the CLI.
Configuration¶
The CLI requires a project configuration with the project name, server URL, and user token in ~/.dstack/config.yml.
projects:
- name: main
url: http://127.0.0.1:3000
token: <user token>
default: true
- name: octocat
url: https://sky.dstack.ai
token: <user token>
Use dstack project to list,
add, delete, and set the default
project configurations. To run a command against a non-default project, pass
--project NAME, or set DSTACK_PROJECT in the current shell.
Projects
Projects enable the isolation of different teams and their resources. Users can be added to projects and assigned roles. Each user has a user token for authentication.
Manage fleets¶
Before submitting runs, you must create at least one fleet. Fleets act as both pools of instances and templates for how those instances are provisioned.
Use dstack fleet to
list existing fleets, their configurations, and instances (if any):
$ dstack fleet
Offers
Offers are available instance configurations that match resource requirements.
$ dstack offer --gpu H100 --max-offers 10
If no fleet is specified,
dstack offer shows offers from all
configured backends.
Use --fleet NAME to restrict offers to a fleet. Listing offers does not
create capacity.
Define a fleet configuration in a YAML file. The filename must end with
.dstack.yml, for example fleet.dstack.yml:
type: fleet
name: default
nodes: 0..1
idle_duration: 1h
resources:
gpu: 0
Pass the fleet configuration to dstack apply:
$ dstack apply -f fleet.dstack.yml
If the nodes range starts with 0, dstack creates a fleet template.
Instances are provisioned when matching runs are submitted.
Submit runs¶
To submit a run, define a dev environment, task, or service configuration. The example below submits a task.
type: task
name: hello
commands:
- echo hello world
Submit the run:
$ dstack apply -f .dstack.yml
Plan and confirmation
dstack apply shows the plan and asks for confirmation before submitting
the run. To only see the plan, answer n at the prompt:
$ echo "n" | dstack apply -f .dstack.yml
Use -y to skip confirmation.
Attached by default
For run configurations, dstack apply automatically attaches after
submitting the run. This streams logs, forwards declared ports, and
configures SSH access. See Attach to runs.
Use -d to submit in detached mode.
Attach to runs¶
If the run was submitted with -d, or if you need to attach to another job in
a multi-job run, use dstack attach:
$ dstack attach <run name>
SSH
During dstack apply in attached mode and during
dstack attach <run name>, the CLI downloads the current user's built-in
private SSH key if needed and stores it under ~/.dstack/ssh/.
While attached, the CLI updates ~/.dstack/ssh/config with the run name as
an SSH host alias and ensures this file is included from ~/.ssh/config:
Host <run name>
HostName localhost
Port <local SSH port>
User root
IdentityFile ~/.dstack/ssh/<key>
IdentitiesOnly yes
For VM-based and SSH fleets, dstack may also configure the
<run name>-host alias for SSH access to the host.
While attached, connect to the run with:
$ ssh <run name>
Use --job JOB_NUMBER with dstack attach to attach to another job. Ports
declared in the run configuration are forwarded while attached.
User SSH keys
The server stores a built-in SSH key pair for each user.
Users can add custom public SSH keys via the UI or the
users API. To use a custom private key for a
particular run, pass --ssh-identity to dstack apply or dstack attach.
Browse logs¶
When dstack apply is attached, it streams logs for job 0 automatically.
Use dstack logs to view logs in detached
mode, or to view logs for a specific job:
$ dstack logs <run name>
Use --job JOB_NUMBER to select a job and --since to filter by time.
Attached logs
Use --logs with dstack attach to stream logs while attaching:
$ dstack attach <run name> --logs
Commands¶
Other common CLI commands include dstack ps,
dstack stop, and
dstack event.
Verbose and JSON modes
Use -v for more details where supported. For automation, use --json,
e.g. dstack ps --json, dstack run get <run name> --json, or
dstack fleet get <fleet name> --json.
API¶
The dstack API is represented by the HTTP API. Use it for functionality not
available in the CLI or for integrations that need to call the server directly.
Authenticate¶
The HTTP API requires the Authorization header for user authentication:
Authorization: Bearer <user token>
Manage fleets¶
The fleets API can list existing fleets, their configurations, and instances (if any):
$ curl "<server URL>/api/project/<project name>/fleets/list" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{"include_imported": true}'
Offers
To check available offers via the HTTP API, call
/runs/get_plan with the same lightweight
task specification used by dstack offer:
$ curl "<server URL>/api/project/<project name>/runs/get_plan" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"run_spec": {
"configuration": {
"type": "task",
"commands": [":"],
"image": "scratch",
"user": "root",
"resources": {
"gpu": 0
}
}
},
"max_offers": 5
}'
If fleets is not set in the run configuration, offers are returned from
all configured backends. Use "fleets": ["default"] to restrict offers to
a fleet.
To group offers by GPU and other fields, use the gpus API.
Creating fleets uses /fleets/get_plan followed by /fleets/apply:
$ curl "<server URL>/api/project/<project name>/fleets/get_plan" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"spec": {
"configuration": {
"type": "fleet",
"name": "cpu-fleet",
"nodes": "0..1",
"idle_duration": "1h",
"resources": {
"gpu": 0
}
},
"profile": {}
}
}'
Then apply the fleet plan:
$ curl "<server URL>/api/project/<project name>/fleets/apply" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"plan": {
"spec": {
"configuration": {
"type": "fleet",
"name": "cpu-fleet",
"nodes": "0..1",
"idle_duration": "1h",
"resources": {
"gpu": 0
}
},
"profile": {}
}
},
"force": false
}'
Submit runs¶
Use the runs API to submit dev environments, tasks, and services. The example below submits a task:
$ curl "<server URL>/api/project/<project name>/runs/apply" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"plan": {
"run_spec": {
"run_name": "hello-api",
"configuration": {
"type": "task",
"commands": ["echo hello world"]
}
}
},
"force": false
}'
Set run_name if a stable run name is needed. Otherwise, the server can
generate a run name.
Poll /runs/get to check the run status:
$ curl "<server URL>/api/project/<project name>/runs/get" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{"run_name": "hello-api"}'
Poll logs¶
Use the logs API to poll logs. Get
job_submission_id from /runs/get, e.g. from latest_job_submission.id.
$ curl "<server URL>/api/project/<project name>/logs/poll" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"run_name": "hello-api",
"job_submission_id": "<job submission id>",
"limit": 100
}'
Use next_token from the response to continue polling.
Reference¶
For complete details on specific CLI commands and HTTP APIs, see the
dstack server and
server references.
OpenAPI
For complete information on the HTTP API, or to generate native clients, refer to openapi.json.
What's next?
- Follow the installation guide
- Read about projects
- Check fleets, dev environments, tasks, and services