Skip to content

Commit d9661b4

Browse files
[UX] Simplify the use of Docker inside containers #2468 (#2828)
1 parent f4c9604 commit d9661b4

5 files changed

Lines changed: 245 additions & 54 deletions

File tree

src/dstack/_internal/core/compatibility/runs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ def get_run_spec_excludes(run_spec: RunSpec) -> Optional[Dict]:
9797
configuration_excludes["rate_limits"] = True
9898
if configuration.shell is None:
9999
configuration_excludes["shell"] = True
100+
if configuration.docker is None:
101+
configuration_excludes["docker"] = True
100102
if configuration.priority is None:
101103
configuration_excludes["priority"] = True
102104
if configuration.startup_order is None:

src/dstack/_internal/core/models/configurations.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,14 @@ class BaseRunConfiguration(CoreModel):
194194
] = None
195195
python: Annotated[
196196
Optional[PythonVersion],
197-
Field(description="The major version of Python. Mutually exclusive with `image`"),
197+
Field(
198+
description="The major version of Python. Mutually exclusive with `image` and `docker`"
199+
),
198200
] = None
199201
nvcc: Annotated[
200202
Optional[bool],
201203
Field(
202-
description="Use image with NVIDIA CUDA Compiler (NVCC) included. Mutually exclusive with `image`"
204+
description="Use image with NVIDIA CUDA Compiler (NVCC) included. Mutually exclusive with `image` and `docker`"
203205
),
204206
] = None
205207
single_branch: Annotated[
@@ -244,6 +246,12 @@ class BaseRunConfiguration(CoreModel):
244246
volumes: Annotated[
245247
List[Union[MountPoint, str]], Field(description="The volumes mount points")
246248
] = []
249+
docker: Annotated[
250+
Optional[bool],
251+
Field(
252+
description="Use Docker inside the container. Mutually exclusive with `image`, `python`, and `nvcc`. Overrides `privileged`"
253+
),
254+
] = None
247255
# deprecated since 0.18.31; task, service -- no effect; dev-environment -- executed right before `init`
248256
setup: CommandsList = []
249257

@@ -259,6 +267,18 @@ def convert_python(cls, v, values) -> Optional[PythonVersion]:
259267
return PythonVersion(v)
260268
return v
261269

270+
@validator("docker", pre=True, always=True)
271+
def _docker(cls, v, values) -> Optional[bool]:
272+
if v is True and values.get("image"):
273+
raise KeyError("`image` and `docker` are mutually exclusive fields")
274+
if v is True and values.get("python"):
275+
raise KeyError("`python` and `docker` are mutually exclusive fields")
276+
if v is True and values.get("nvcc"):
277+
raise KeyError("`nvcc` and `docker` are mutually exclusive fields")
278+
# Ideally, we'd like to also prohibit privileged=False when docker=True,
279+
# but it's not possible to do so without breaking backwards compatibility.
280+
return v
281+
262282
@validator("volumes", each_item=True)
263283
def convert_volumes(cls, v) -> MountPoint:
264284
if isinstance(v, str):

src/dstack/_internal/server/services/jobs/configurators/base.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ async def _commands(self) -> List[str]:
171171
return result
172172

173173
def _dstack_image_commands(self) -> List[str]:
174+
if self.run_spec.configuration.docker is True:
175+
return ["start-dockerd"]
174176
if (
175177
self.run_spec.configuration.image is not None
176178
or self.run_spec.configuration.entrypoint is not None
@@ -201,7 +203,9 @@ def _home_dir(self) -> Optional[str]:
201203
return self.run_spec.configuration.home_dir
202204

203205
def _image_name(self) -> str:
204-
if self.run_spec.configuration.image is not None:
206+
if self.run_spec.configuration.docker is True:
207+
return settings.DSTACK_DIND_IMAGE
208+
elif self.run_spec.configuration.image is not None:
205209
return self.run_spec.configuration.image
206210
return get_default_image(nvcc=bool(self.run_spec.configuration.nvcc))
207211

@@ -215,6 +219,8 @@ async def _user(self) -> Optional[UnixUser]:
215219
return UnixUser.parse(user)
216220

217221
def _privileged(self) -> bool:
222+
if self.run_spec.configuration.docker is True:
223+
return True
218224
return self.run_spec.configuration.privileged
219225

220226
def _single_branch(self) -> bool:

src/dstack/_internal/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
DSTACK_BASE_IMAGE_UBUNTU_VERSION = os.getenv(
1818
"DSTACK_BASE_IMAGE_UBUNTU_VERSION", version.base_image_ubuntu_version
1919
)
20+
DSTACK_DIND_IMAGE = os.getenv("DSTACK_DIND_IMAGE", "dstackai/dind")
2021

2122

2223
class FeatureFlags:

0 commit comments

Comments
 (0)