Skip to content

Commit 17daee5

Browse files
authored
feat: Add a global cache for uv, pre-commit and global venv (#307)
Supercedes #304 and #305 by adding a global volume that contains: - pre-commit cache - uv cache - uv managed python cache - the venvs for all the projects This allows us to use hardlink mode which makes it even faster, and avoid the issue of anonymous volumes in devcontainers being left dangling. Added docs to say that there is now a global venv for the container, which is different for how it would look without any environment variables set
1 parent ae18808 commit 17daee5

File tree

3 files changed

+25
-18
lines changed

3 files changed

+25
-18
lines changed

.devcontainer/devcontainer.json

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,22 @@
88
"remoteEnv": {
99
// Allow X11 apps to run inside the container
1010
"DISPLAY": "${localEnv:DISPLAY}",
11+
// Put things that allow it in the persistent cache
12+
"PRE_COMMIT_HOME": "/cache/pre-commit",
13+
"UV_CACHE_DIR": "/cache/uv",
14+
"UV_PYTHON_CACHE_DIR": "/cache/uv-python",
15+
// Make a venv that is specific for this workspace path as the cache is shared
16+
"UV_PROJECT_ENVIRONMENT": "/cache/venv-for${localWorkspaceFolder}",
1117
// Do the equivalent of "activate" the venv so we don't have to "uv run" everything
12-
"VIRTUAL_ENV": "/workspaces/${localWorkspaceFolderBasename}/.venv",
13-
"PATH": "/workspaces/${localWorkspaceFolderBasename}/.venv/bin:${containerEnv:PATH}"
18+
"VIRTUAL_ENV": "/cache/venv-for${localWorkspaceFolder}",
19+
"PATH": "/cache/venv-for${localWorkspaceFolder}/bin:${containerEnv:PATH}"
1420
},
1521
"customizations": {
1622
"vscode": {
1723
// Set *default* container specific settings.json values on container create.
1824
"settings": {
1925
// Use the container's python by default
20-
"python.defaultInterpreterPath": "/workspaces/${localWorkspaceFolderBasename}/.venv/bin/python",
26+
"python.defaultInterpreterPath": "/cache/venv-for${localWorkspaceFolder}/bin/python",
2127
// Don't activate the venv as it is already in the PATH
2228
"python.terminal.activateEnvInCurrentTerminal": false,
2329
"python.terminal.activateEnvironment": false,
@@ -38,9 +44,7 @@
3844
}
3945
},
4046
// Create the config folder for the bash-config feature and uv cache
41-
// NOTE: The uv cache can get large, DLS users should read
42-
// https://dev-guide.diamond.ac.uk/linux-user-environment/how-tos/disk-quota-troubleshooting
43-
"initializeCommand": "mkdir -p ${localEnv:HOME}/.config/terminal-config ${localEnv:HOME}/.cache/uv",
47+
"initializeCommand": "mkdir -p ${localEnv:HOME}/.config/terminal-config",
4448
"runArgs": [
4549
// Allow the container to access the host X11 display and EPICS CA
4650
"--net=host",
@@ -54,20 +58,15 @@
5458
"target": "/user-terminal-config",
5559
"type": "bind"
5660
},
57-
// Keep a persistent cross container cache for uv
61+
// Keep a persistent cross container cache for uv, pre-commit, and the venvs
5862
{
59-
"source": "${localEnv:HOME}/.cache/uv",
60-
"target": "/root/.cache/uv",
61-
"type": "bind"
62-
},
63-
// Use a volume mount for the uv venv so it is local to the container
64-
{
65-
"target": "/workspaces/${localWorkspaceFolderBasename}/.venv",
63+
"source": "devcontainer-shared-cache",
64+
"target": "/cache",
6665
"type": "volume"
6766
}
6867
],
6968
// Mount the parent as /workspaces so we can pip install peers as editable
7069
"workspaceMount": "source=${localWorkspaceFolder}/..,target=/workspaces,type=bind",
71-
// After the container is created, install the python project in editable form
72-
"postCreateCommand": "uv sync && uv run pre-commit install --install-hooks"
70+
// After the container is created, recreate the venv then make pre-commit first run faster
71+
"postCreateCommand": "uv venv --clear && uv sync && pre-commit install --install-hooks"
7372
}

docs/how-to/dev-install.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ code .
2020

2121
Click on 'Reopen in Container' when prompted on startup or, if vscode is already running, open the command menu with CTRL+SHIFT+P, search for and run 'Reopen in Container'.
2222

23-
Open a new terminal
23+
The developer container creates and activates a venv (stored in `/cache/venv-for/path/to/project`) and this will be managed by any `uv sync` command as explained in [](./lock-requirements.md). Any rebuild of the container will recreate this venv, but the dependencies will be stored in a cross container cache so that rebuilds are quick.
2424

2525
## Build and test
2626

27-
Now you have a development environment you can run the tests in a terminal:
27+
Now you have a development environment you can run the tests in a new terminal:
2828

2929
```
3030
tox -p

docs/how-to/lock-requirements.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,11 @@ uv sync --upgrade
3232
```{seealso}
3333
[The uv docs on locking and syncing](https://docs.astral.sh/uv/concepts/projects/sync)
3434
```
35+
36+
## Modifying the venv to add other projects
37+
38+
Peer projects (those checked out next to the project) are visible in the devcontainer, and can be added into the venv by running `uv pip install -e ../other_project`. This will allow live changes made in this other project to be immediately reflected in the venv.
39+
40+
```{note}
41+
This venv is activated by default, and global to the container, so if you `uv sync` from `other_project` then it will **replace** the contents of the venv with `other_project`'s dependencies.
42+
```

0 commit comments

Comments
 (0)