@@ -220,6 +220,17 @@ def _dstack_image_commands(self) -> List[str]:
220220 ):
221221 return []
222222 return [
223+ f"eval $(echo 'export DSTACK_VENV_DIR={ DSTACK_DIR } /venv' | sudo tee -a { DSTACK_PROFILE_PATH } )" ,
224+ # Make sure /dstack/venv is owned by the current user.
225+ # XXX: Generally, /dstack and all its descendants should be owned by root, as it is
226+ # intended to be a place for files shared by all users, but since a non-root user
227+ # should be able to install packages via pip and we want to avoid cluttering the user's
228+ # home dir if possible, we make the venv dir owned by the current user rather than
229+ # creating it inside the user's home or (even worse) making /dstack/venv
230+ # world-writable.
231+ "sudo rm -rf $DSTACK_VENV_DIR" ,
232+ "sudo mkdir $DSTACK_VENV_DIR" ,
233+ "sudo chown $(id -u):$(id -g) $DSTACK_VENV_DIR" ,
223234 # `uv` may emit:
224235 # > warning: `VIRTUAL_ENV=/dstack/venv` does not match the project environment path
225236 # > `.venv` and will be ignored; use `--active` to target the active environment
@@ -228,9 +239,8 @@ def _dstack_image_commands(self) -> List[str]:
228239 # used for legacy `pip`-based configurations). `--no-active` suppresses the warning.
229240 # Alternatively, the user can call `deactivate` once before using `uv`.
230241 # If the user really wants to reuse dstack's venv, they must spefify `--active`.
231- f"uv venv -q --prompt dstack -p { self ._python ()} --seed { DSTACK_DIR } /venv" ,
232- f"echo '. { DSTACK_DIR } /venv/bin/activate' >> { DSTACK_PROFILE_PATH } " ,
233- f". { DSTACK_DIR } /venv/bin/activate" ,
242+ f"uv venv -q --prompt dstack -p { self ._python ()} --seed $DSTACK_VENV_DIR" ,
243+ f"eval $(echo '. $DSTACK_VENV_DIR/bin/activate' | sudo tee -a { DSTACK_PROFILE_PATH } )" ,
234244 ]
235245
236246 def _app_specs (self ) -> List [AppSpec ]:
0 commit comments