You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# dstack 0.20 GA: Fleet-first UX and other important changes
15
+
16
+
We’re releasing `dstack` 0.20.0, a major update that improves how teams orchestrate GPU workloads for development, training, and inference. Most `dstack` updates are incremental and backward compatible, but this version introduces a few major changes to how you work with `dstack`.
17
+
18
+
In `dstack` 0.20.0, fleets are now a first-class concept, giving you more explicit control over how GPU capacity is provisioned and managed. We’ve also added *Events*, which record important system activity—such as scheduling decisions, run status changes, and resource lifecycle updates—so it’s easier to understand what’s happening without digging through server logs.
This post goes through the changes in detail and explains how to upgrade and migrate your existing setup.
23
+
24
+
<!-- more -->
25
+
26
+
## Fleets
27
+
28
+
In earlier versions, submitting a run that didn’t match any existing fleet would cause `dstack` to automatically create one. While this reduced setup overhead, it also made capacity provisioning implicit and less predictable.
29
+
30
+
With `dstack` 0.20.0, fleets must be created explicitly and treated as first-class resources. This shift makes capacity provisioning declarative, improving control over resource limits, instance lifecycles, and overall fleet behavior.
31
+
32
+
For users who previously relied on auto-created fleets, similar behavior can be achieved by defining an elastic fleet, for example:
33
+
34
+
<diveditor-title="fleet.dstack.yml">
35
+
36
+
```yaml
37
+
type: fleet
38
+
# The name is optional, if not specified, generated randomly
39
+
name: default
40
+
41
+
# Can be a range or a fixed number
42
+
# Allow to provision up to 2 instances
43
+
nodes: 0..2
44
+
45
+
# Uncomment to ensure instances are inter-connected
46
+
#placement: cluster
47
+
48
+
# Deprovision instances above the minimum if they remain idle
49
+
idle_duration: 1h
50
+
51
+
resources:
52
+
# Allow to provision up to 8 GPUs
53
+
gpu: 0..8
54
+
```
55
+
56
+
</div>
57
+
58
+
If the `nodes` range starts above `0`, `dstack` provisions the initial capacity upfront and scales additional instances on demand, enabling more predictable capacity planning.
59
+
60
+
When a run does not explicitly reference a fleet (via the [`fleets`](../../docs/reference/dstack.yml/dev-environment.md#fleets) property), `dstack` automatically selects one that satisfies the run’s requirements.
61
+
62
+
## Events
63
+
64
+
Previously, when `dstack` changed the state of a run or other resource, that information was written only to the server logs. This worked for admins, but it made it hard for users to understand what happened or why.
65
+
66
+
Starting with version `0.20.0`, `dstack` exposes these events directly to users.
67
+
68
+
Each resource now includes an `Events` tab in the UI, showing related events in real time:
There is also a dedicated `Events` page that aggregates events across resources. You can filter by project, user, run, or job to quickly narrow down what you’re looking for:
This makes it easier to track state changes, debug issues, and review past actions without needing access to server logs.
81
+
82
+
## Runs
83
+
84
+
This release updates several defaults related to run configuration. The goal is to reduce implicit assumptions and make it more convenient.
85
+
86
+
### Working directory
87
+
88
+
Previously, the `working_dir` property defaulted to `/workflow`. Now, the default working directory is always taken from the Docker image.
89
+
90
+
The working directory in the default Docker images (if you don't specify `image`) is now set to `/dstack/run`.
91
+
92
+
### Repo directory
93
+
94
+
Previously, if you didn't specify a repo path, the repo was cloned to `/workflow`. Now, in that case the repo will be cloned to the working directory.
95
+
96
+
<diveditor-title="examples/.dstack.yml">
97
+
98
+
```yaml
99
+
type: dev-environment
100
+
name: vscode
101
+
102
+
repos:
103
+
# Clones the repo from the parent directory (`examples/..`) to `<working dir>`
104
+
- ..
105
+
106
+
ide: vscode
107
+
```
108
+
109
+
</div>
110
+
111
+
Also, now if the repo directory is not empty, the run will fail with an error.
112
+
113
+
## Backward compatibility
114
+
115
+
While the update introduces breaking changes, 0.19.* CLIs remain compatible with 0.20.* servers.
116
+
117
+
> Note, the 0.20.* CLI only works with a 0.20.* server.
118
+
119
+
!!! warning "Breaking changes"
120
+
This release introduces breaking changes that may affect existing setups. Before upgrading either the CLI or the server, review the [migration guide](https://dstack.ai/docs/guides/migration/#0_20).
121
+
122
+
## What's next
123
+
124
+
1. Follow the [Installation](../../docs/installation/index.md) guide
125
+
2. Try the [Quickstart](../../docs/quickstart.md)
126
+
3. Report issues on [GitHub](https://github.com/dstackai/dstack/issues)
127
+
4. Ask questions on [Discord](https://discord.gg/u8SmfwPpMd)
Copy file name to clipboardExpand all lines: docs/docs/concepts/dev-environments.md
+32-21Lines changed: 32 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -301,11 +301,11 @@ If you don't assign a value to an environment variable (see `HF_TOKEN` above),
301
301
302
302
### Working directory
303
303
304
-
If `working_dir` is not specified, it defaults to `/workflow`.
304
+
If `working_dir` is not specified, it defaults to the working directory set in the Docker image. For example, the [default image](#default-image) uses `/dstack/run` as its working directory.
305
305
306
-
The `working_dir` must be an absolute path. The tilde (`~`) is supported (e.g., `~/my-working-dir`).
306
+
If the Docker image does not have a working directory set, `dstack` uses `/` as the `working_dir`.
307
307
308
-
<!-- TODO: In a future version, the default working directory will be taken from `image`. -->
308
+
The `working_dir` must be an absolute path. The tilde (`~`) is supported (e.g., `~/my-working-dir`).
309
309
310
310
<!-- TODO: Elaborate on `entrypoint` -->
311
311
@@ -320,7 +320,7 @@ type: dev-environment
320
320
name: vscode
321
321
322
322
files:
323
-
- .:examples # Maps the directory where`.dstack.yml` to `/workflow/examples`
323
+
- .:examples # Maps the directory with`.dstack.yml` to `<working dir>/examples`
324
324
- ~/.ssh/id_rsa:/root/.ssh/id_rsa # Maps `~/.ssh/id_rsa` to `/root/.ssh/id_rsa`
325
325
326
326
ide: vscode
@@ -329,7 +329,7 @@ ide: vscode
329
329
</div>
330
330
331
331
If the local path is relative, it’s resolved relative to the configuration file.
332
-
If the container path is relative, it’s resolved relative to `/workflow`.
332
+
If the container path is relative, it’s resolved relative to the [working directory](#working-directory).
333
333
334
334
The container path is optional. If not specified, it will be automatically calculated:
335
335
@@ -340,7 +340,7 @@ type: dev-environment
340
340
name: vscode
341
341
342
342
files:
343
-
- ../examples # Maps `examples` (the parent directory of `.dstack.yml`) to `/workflow/examples`
343
+
- ../examples # Maps the parent directory of `.dstack.yml` to `<working dir>/../examples`
344
344
- ~/.ssh/id_rsa # Maps `~/.ssh/id_rsa` to `/root/.ssh/id_rsa`
345
345
346
346
ide: vscode
@@ -355,9 +355,9 @@ ide: vscode
355
355
356
356
### Repos
357
357
358
-
Sometimes, you may want to mount an entire Git repo inside the container.
358
+
Sometimes, you may want to clone an entire Git repo inside the container.
359
359
360
-
Imagine you have a cloned Git repo containing an `examples` subdirectory with a `.dstack.yml` file:
360
+
Imagine you have a Git repo (clonned locally) containing an `examples` subdirectory with a `.dstack.yml` file:
361
361
362
362
<div editor-title="examples/.dstack.yml">
363
363
@@ -366,24 +366,21 @@ type: dev-environment
366
366
name: vscode
367
367
368
368
repos:
369
-
# Mounts the parent directory of `examples` (must be a Git repo)
370
-
# to `/workflow` (the default working directory)
369
+
# Clones the repo from the parent directory (`examples/..`) to `<working dir>`
371
370
- ..
372
371
373
372
ide: vscode
374
373
```
375
374
376
375
</div>
377
376
378
-
When you run it, `dstack` fetches the repo on the instance, applies your local changes, and mounts it—so the container matches your local repo.
377
+
When you run it, `dstack` clones the repo on the instance, applies your local changes, and mounts it—so the container matches your local repo.
379
378
380
379
The local path can be either relative to the configuration file or absolute.
381
380
382
381
??? info "Repo directory"
383
-
By default, `dstack` mounts the repo to `/workflow` (the default working directory).
382
+
By default, `dstack` clones the repo to the [working directory](#working-directory).
384
383
385
-
<!-- TODO: In a future version, the default working directory will come from the image, so this should be revisited. -->
386
-
387
384
You can override the repo directory using either a relative or an absolute path:
388
385
389
386
<div editor-title="examples/.dstack.yml">
@@ -393,16 +390,30 @@ The local path can be either relative to the configuration file or absolute.
393
390
name: vscode
394
391
395
392
repos:
396
-
# Mounts the parent directory of `examples` (must be a Git repo)
397
-
# to `/my-repo`
393
+
# Clones the repo in the parent directory (`examples/..`) to `/my-repo`
398
394
- ..:/my-repo
399
395
400
396
ide: vscode
401
397
```
402
398
403
399
</div>
404
400
405
-
If the path is relative, it is resolved against [working directory](#working-directory).
401
+
> If the repo directory is relative, it is resolved against [working directory](#working-directory).
402
+
403
+
If the repo directory is not empty, the run will fail with a runner error.
404
+
To override this behavior, you can set `if_exists` to `skip`:
405
+
406
+
```yaml
407
+
type: dev-environment
408
+
name: vscode
409
+
410
+
repos:
411
+
- local_path: ..
412
+
path: /my-repo
413
+
if_exists: skip
414
+
415
+
ide: vscode
416
+
```
406
417
407
418
408
419
??? info "Repo size"
@@ -411,7 +422,7 @@ The local path can be either relative to the configuration file or absolute.
411
422
You can increase the 2MB limit by setting the `DSTACK_SERVER_CODE_UPLOAD_LIMIT` environment variable.
412
423
413
424
??? info "Repo URL"
414
-
Sometimes you may want to mount a Git repo without cloning it locally. In this case, simply provide a URL in `repos`:
425
+
Sometimes you may want to clone a Git repo within the container without cloning it locally. In this case, simply provide a URL in `repos`:
415
426
416
427
<div editor-title="examples/.dstack.yml">
417
428
@@ -420,7 +431,7 @@ The local path can be either relative to the configuration file or absolute.
420
431
name: vscode
421
432
422
433
repos:
423
-
# Clone the specified repo to `/workflow` (the default working directory)
434
+
# Clone the repo to `<working dir>`
424
435
- https://github.com/dstackai/dstack
425
436
426
437
ide: vscode
@@ -432,9 +443,9 @@ The local path can be either relative to the configuration file or absolute.
432
443
If a Git repo is private, `dstack` will automatically try to use your default Git credentials (from
433
444
`~/.ssh/config`or `~/.config/gh/hosts.yml`).
434
445
435
-
If you want to use custom credentials, you can provide them with [`dstack init`](../reference/cli/dstack/init.md).
446
+
> If you want to use custom credentials, ensure to pass them via [`dstack init`](../reference/cli/dstack/init.md) before submitting a run.
436
447
437
-
> Currently, you can configure up to one repo per run configuration.
448
+
Currently, you can configure up to one repo per run configuration.
0 commit comments