From c28d034734e1658f578af90f9a5d6a454435b2ee Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Tue, 6 Jan 2026 09:09:18 +0000 Subject: [PATCH 01/14] add fnm feature --- features/fnm/devcontainer-feature.json | 13 +++++++++++++ features/fnm/install.sh | 9 +++++++++ 2 files changed, 22 insertions(+) create mode 100644 features/fnm/devcontainer-feature.json create mode 100755 features/fnm/install.sh diff --git a/features/fnm/devcontainer-feature.json b/features/fnm/devcontainer-feature.json new file mode 100644 index 0000000..38d8d70 --- /dev/null +++ b/features/fnm/devcontainer-feature.json @@ -0,0 +1,13 @@ +{ + "id": "fnm", + "version": "1.0.0", + "name": "Fast Node Manager (fnm)", + "description": "Installs fnm and optionally a Node.js version.", + "options": { + "nodeVersion": { + "type": "string", + "default": "lts", + "description": "Node.js version to install with fnm (use 'none' to skip)." + } + } +} diff --git a/features/fnm/install.sh b/features/fnm/install.sh new file mode 100755 index 0000000..45ab49c --- /dev/null +++ b/features/fnm/install.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +curl -fsSL https://fnm.vercel.app/install | bash + +NODE_VERSION="${NODE_VERSION:-lts}" +if [ "$NODE_VERSION" != "none" ]; then + fnm install "$NODE_VERSION" +fi From f331cb98ea9cb7286925a78d798819f72c528474 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Tue, 6 Jan 2026 09:20:38 +0000 Subject: [PATCH 02/14] improve feature fnm --- features/fnm/devcontainer-feature.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/fnm/devcontainer-feature.json b/features/fnm/devcontainer-feature.json index 38d8d70..6a8e668 100644 --- a/features/fnm/devcontainer-feature.json +++ b/features/fnm/devcontainer-feature.json @@ -7,7 +7,7 @@ "nodeVersion": { "type": "string", "default": "lts", - "description": "Node.js version to install with fnm (use 'none' to skip)." + "description": "Node.js version to install with fnm. Use 'none' to skip." } } } From 895912a1b44e69eb5e513fa1c85303f9a3f377f6 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Tue, 6 Jan 2026 09:20:52 +0000 Subject: [PATCH 03/14] add feature of uv --- features/uv/devcontainer-feature.json | 13 +++++++++++++ features/uv/install.sh | 9 +++++++++ 2 files changed, 22 insertions(+) create mode 100644 features/uv/devcontainer-feature.json create mode 100755 features/uv/install.sh diff --git a/features/uv/devcontainer-feature.json b/features/uv/devcontainer-feature.json new file mode 100644 index 0000000..36c5327 --- /dev/null +++ b/features/uv/devcontainer-feature.json @@ -0,0 +1,13 @@ +{ + "id": "uv", + "version": "1.0.0", + "name": "uv", + "description": "Installs uv and optionally a Python version.", + "options": { + "pythonVersion": { + "type": "string", + "default": "3", + "description": "Python version to install with uv. Use 'none' to skip." + } + } +} diff --git a/features/uv/install.sh b/features/uv/install.sh new file mode 100755 index 0000000..292d472 --- /dev/null +++ b/features/uv/install.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +curl -LsSf https://astral.sh/uv/install.sh | sh + +PYTHON_VERSION="${PYTHON_VERSION:-3}" +if [ "$PYTHON_VERSION" != "none" ]; then + uv python install --default "$PYTHON_VERSION" +fi From 1bf52518be05ced1531c9c9492d824dd0f607876 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Tue, 6 Jan 2026 10:27:42 +0000 Subject: [PATCH 04/14] fix feature of fnm --- features/fnm/install.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/features/fnm/install.sh b/features/fnm/install.sh index 45ab49c..955c004 100755 --- a/features/fnm/install.sh +++ b/features/fnm/install.sh @@ -1,9 +1,18 @@ #!/usr/bin/env bash +if [ -z "${BASH_VERSION:-}" ]; then + exec bash "$0" "$@" +fi + set -euo pipefail curl -fsSL https://fnm.vercel.app/install | bash +. "$HOME/.bashrc" NODE_VERSION="${NODE_VERSION:-lts}" if [ "$NODE_VERSION" != "none" ]; then - fnm install "$NODE_VERSION" + if [ "$NODE_VERSION" = "lts" ]; then + fnm install --lts + else + fnm install "$NODE_VERSION" + fi fi From ad38d852bf19f3d0e9b46645381aff0580bd7ed4 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Tue, 6 Jan 2026 12:00:58 +0000 Subject: [PATCH 05/14] fix --- features/uv/install.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/features/uv/install.sh b/features/uv/install.sh index 292d472..769ed69 100755 --- a/features/uv/install.sh +++ b/features/uv/install.sh @@ -1,7 +1,12 @@ #!/usr/bin/env bash +if [ -z "${BASH_VERSION:-}" ]; then + exec bash "$0" "$@" +fi + set -euo pipefail curl -LsSf https://astral.sh/uv/install.sh | sh +. $HOME/.local/bin/env PYTHON_VERSION="${PYTHON_VERSION:-3}" if [ "$PYTHON_VERSION" != "none" ]; then From 6892e9c996623bccc282891aad519d11eeab9fc5 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Tue, 6 Jan 2026 12:29:10 +0000 Subject: [PATCH 06/14] fix --- features/fnm/install.sh | 4 ++-- features/uv/install.sh | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/fnm/install.sh b/features/fnm/install.sh index 955c004..387a254 100755 --- a/features/fnm/install.sh +++ b/features/fnm/install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -if [ -z "${BASH_VERSION:-}" ]; then - exec bash "$0" "$@" +if [ -z "${BASH_VERSION:-}" ] || [ "$(id -un)" != "$_REMOTE_USER" ]; then + exec su - "$_REMOTE_USER" -c "bash -lc '$0'" fi set -euo pipefail diff --git a/features/uv/install.sh b/features/uv/install.sh index 769ed69..62129a0 100755 --- a/features/uv/install.sh +++ b/features/uv/install.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -if [ -z "${BASH_VERSION:-}" ]; then - exec bash "$0" "$@" +if [ -z "${BASH_VERSION:-}" ] || [ "$(id -un)" != "$_REMOTE_USER" ]; then + exec su - "$_REMOTE_USER" -c "bash -lc '$0'" fi set -euo pipefail curl -LsSf https://astral.sh/uv/install.sh | sh -. $HOME/.local/bin/env +. "$HOME/.local/bin/env" PYTHON_VERSION="${PYTHON_VERSION:-3}" if [ "$PYTHON_VERSION" != "none" ]; then From 4696a2303c9a5028c19716c661b00f2aeb9ea565 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Wed, 7 Jan 2026 03:37:40 +0000 Subject: [PATCH 07/14] refactor(devcontainer): simplify compose setup --- README.md | 11 +++-------- compose-base/docker-compose.yaml | 12 ------------ .../.template/.devcontainer/devcontainer.json | 16 ++++++++-------- projects/.template/docker-compose.yaml | 3 +-- 4 files changed, 12 insertions(+), 30 deletions(-) delete mode 100644 compose-base/docker-compose.yaml diff --git a/README.md b/README.md index 7569a6c..6637885 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # VS Code Dev Container Playground -This repository provides a template-based workflow for VS Code Dev Containers. Shared settings live under `compose-base/`, and each local dev container is created by copying `projects/.template/` into `projects/`. +This repository provides a template-based workflow for VS Code Dev Containers. Each local dev container is created by copying `projects/.template/` into `projects/`. ## Getting Started @@ -9,11 +9,6 @@ Prerequisites: Docker is available on the host, and VS Code has the `ms-vscode-r 1. Download the repository (e.g., `git clone https://github.com/iplaylf2/vscode-container.git`). 2. Copy `projects/.template/` to `projects/`. 3. Edit `projects//docker-compose.yaml` as needed. -4. Set `VSCODE_CONTAINER_PROJECT` in the host environment that will launch VS Code. -5. Open `projects/` in VS Code and run `Dev Containers: Reopen in Container`. +4. Open `projects/` in VS Code and run `Dev Containers: Reopen in Container`. -After the container is created, VS Code opens the workspace at `/mnt/${VSCODE_CONTAINER_PROJECT}`. The data lives in a Docker volume named `${VSCODE_CONTAINER_PROJECT}`. - -## Configuration Notes - -- `VSCODE_CONTAINER_PROJECT` provides the project identity (volume name and `/mnt/` path); it is an environment variable because `devcontainer.json` cannot pass variables into Docker Compose. +After the container is created, VS Code opens the workspace at `/mnt/`. The data lives in a Docker volume named ``. diff --git a/compose-base/docker-compose.yaml b/compose-base/docker-compose.yaml deleted file mode 100644 index 8b4d962..0000000 --- a/compose-base/docker-compose.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: ${VSCODE_CONTAINER_PROJECT} - -services: - devcontainer: - build: - context: .. - volumes: - - devcontainer-workspace:/mnt/${VSCODE_CONTAINER_PROJECT} - -volumes: - devcontainer-workspace: - name: ${VSCODE_CONTAINER_PROJECT} diff --git a/projects/.template/.devcontainer/devcontainer.json b/projects/.template/.devcontainer/devcontainer.json index fd933b5..0bbf4d3 100644 --- a/projects/.template/.devcontainer/devcontainer.json +++ b/projects/.template/.devcontainer/devcontainer.json @@ -1,11 +1,11 @@ { - "name": "${localEnv:VSCODE_CONTAINER_PROJECT}", - "dockerComposeFile": [ - "../../../compose-base/docker-compose.yaml", - "../docker-compose.yaml" + "dockerComposeFile": "../docker-compose.yaml", + "mounts": [ + "source=${localWorkspaceFolderBasename},target=/mnt/${localWorkspaceFolderBasename},type=volume" ], - "service": "devcontainer", - "workspaceFolder": "/mnt/${localEnv:VSCODE_CONTAINER_PROJECT}", + "name": "${localWorkspaceFolderBasename}", + "overrideCommand": true, "postCreateCommand": "sudo chown vscode ${containerWorkspaceFolder}", - "overrideCommand": true -} + "service": "devcontainer", + "workspaceFolder": "/mnt/${localWorkspaceFolderBasename}" +} \ No newline at end of file diff --git a/projects/.template/docker-compose.yaml b/projects/.template/docker-compose.yaml index 3d8f540..2326893 100644 --- a/projects/.template/docker-compose.yaml +++ b/projects/.template/docker-compose.yaml @@ -1,9 +1,8 @@ services: devcontainer: - # Base settings come from ../../compose-base/docker-compose.yaml via dockerComposeFile. build: # Pick the Dockerfile that matches your dev environment. - dockerfile: images/base/Dockerfile + dockerfile: ../../images/base/Dockerfile args: # Optional: toolchain version for Dockerfiles that accept SDK_VERSION. SDK_VERSION: 0 From 1ce6304d0157991e67436b526b70c09d55857e44 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Wed, 7 Jan 2026 04:50:14 +0000 Subject: [PATCH 08/14] fix --- .vscode/extensions.json | 3 ++- README.md | 2 +- projects/.template/.devcontainer/devcontainer.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e1d2d5a..ddcd8b9 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,8 @@ { "recommendations": [ + "davidanson.vscode-markdownlint", "ms-azuretools.vscode-containers", + "redhat.vscode-yaml", "streetsidesoftware.code-spell-checker", - "redhat.vscode-yaml" ] } \ No newline at end of file diff --git a/README.md b/README.md index 6637885..e457c96 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,4 @@ Prerequisites: Docker is available on the host, and VS Code has the `ms-vscode-r 3. Edit `projects//docker-compose.yaml` as needed. 4. Open `projects/` in VS Code and run `Dev Containers: Reopen in Container`. -After the container is created, VS Code opens the workspace at `/mnt/`. The data lives in a Docker volume named ``. +After the container is created, VS Code opens the workspace at `/mnt/`. The data lives in a Docker volume named `_workspace`. diff --git a/projects/.template/.devcontainer/devcontainer.json b/projects/.template/.devcontainer/devcontainer.json index 0bbf4d3..fc4cab4 100644 --- a/projects/.template/.devcontainer/devcontainer.json +++ b/projects/.template/.devcontainer/devcontainer.json @@ -1,7 +1,7 @@ { "dockerComposeFile": "../docker-compose.yaml", "mounts": [ - "source=${localWorkspaceFolderBasename},target=/mnt/${localWorkspaceFolderBasename},type=volume" + "source=workspace,target=/mnt/${localWorkspaceFolderBasename},type=volume" ], "name": "${localWorkspaceFolderBasename}", "overrideCommand": true, From 5daca0bcc74a7993de6cfe6d4df809339b0c1706 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Wed, 7 Jan 2026 04:51:50 +0000 Subject: [PATCH 09/14] prettier --- features/uv/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/uv/install.sh b/features/uv/install.sh index 62129a0..188db88 100755 --- a/features/uv/install.sh +++ b/features/uv/install.sh @@ -5,7 +5,7 @@ fi set -euo pipefail -curl -LsSf https://astral.sh/uv/install.sh | sh +curl -fsSL https://astral.sh/uv/install.sh | sh . "$HOME/.local/bin/env" PYTHON_VERSION="${PYTHON_VERSION:-3}" From eb089765f3815e2de20b8d25acc8cb40cb10053d Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Wed, 7 Jan 2026 05:43:39 +0000 Subject: [PATCH 10/14] fix --- features/fnm/install.sh | 2 +- features/uv/install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/fnm/install.sh b/features/fnm/install.sh index 387a254..61763fe 100755 --- a/features/fnm/install.sh +++ b/features/fnm/install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash if [ -z "${BASH_VERSION:-}" ] || [ "$(id -un)" != "$_REMOTE_USER" ]; then - exec su - "$_REMOTE_USER" -c "bash -lc '$0'" + exec su "$_REMOTE_USER" -c "bash -lc '$0'" fi set -euo pipefail diff --git a/features/uv/install.sh b/features/uv/install.sh index 188db88..60cae4a 100755 --- a/features/uv/install.sh +++ b/features/uv/install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash if [ -z "${BASH_VERSION:-}" ] || [ "$(id -un)" != "$_REMOTE_USER" ]; then - exec su - "$_REMOTE_USER" -c "bash -lc '$0'" + exec su "$_REMOTE_USER" -c "bash -lc '$0'" fi set -euo pipefail From e17ce9d22d134b461044259dced2e75295668880 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Wed, 7 Jan 2026 06:02:55 +0000 Subject: [PATCH 11/14] improve projects/.template/.devcontainer/devcontainer.json --- projects/.template/.devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/.template/.devcontainer/devcontainer.json b/projects/.template/.devcontainer/devcontainer.json index fc4cab4..8a01cdd 100644 --- a/projects/.template/.devcontainer/devcontainer.json +++ b/projects/.template/.devcontainer/devcontainer.json @@ -5,7 +5,7 @@ ], "name": "${localWorkspaceFolderBasename}", "overrideCommand": true, - "postCreateCommand": "sudo chown vscode ${containerWorkspaceFolder}", + "postCreateCommand": "sudo chown ${remoteUser} ${containerWorkspaceFolder}", "service": "devcontainer", "workspaceFolder": "/mnt/${localWorkspaceFolderBasename}" } \ No newline at end of file From 85a366a2f6cab7e3db714d8a913767b5b72f1626 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Wed, 7 Jan 2026 06:05:28 +0000 Subject: [PATCH 12/14] improve --- projects/.template/.devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/.template/.devcontainer/devcontainer.json b/projects/.template/.devcontainer/devcontainer.json index 8a01cdd..47ab620 100644 --- a/projects/.template/.devcontainer/devcontainer.json +++ b/projects/.template/.devcontainer/devcontainer.json @@ -1,7 +1,7 @@ { "dockerComposeFile": "../docker-compose.yaml", "mounts": [ - "source=workspace,target=/mnt/${localWorkspaceFolderBasename},type=volume" + "source=workspace,target=${containerWorkspaceFolder},type=volume" ], "name": "${localWorkspaceFolderBasename}", "overrideCommand": true, From 1acf5ee57dccef1a74e35976085b9db2aa747ff6 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Wed, 7 Jan 2026 06:58:01 +0000 Subject: [PATCH 13/14] fix features/fnm/install.sh --- features/fnm/install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/fnm/install.sh b/features/fnm/install.sh index 61763fe..9506a6b 100755 --- a/features/fnm/install.sh +++ b/features/fnm/install.sh @@ -6,7 +6,9 @@ fi set -euo pipefail curl -fsSL https://fnm.vercel.app/install | bash -. "$HOME/.bashrc" + +FNM_PATH="$HOME/.local/share/fnm" +export PATH="$FNM_PATH:$PATH" NODE_VERSION="${NODE_VERSION:-lts}" if [ "$NODE_VERSION" != "none" ]; then From b54be85f2529f22bf00cb5094f26357130acddf1 Mon Sep 17 00:00:00 2001 From: i-play-lf2 <914637118@qq.com> Date: Wed, 7 Jan 2026 07:13:02 +0000 Subject: [PATCH 14/14] fix --- projects/.template/.devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/.template/.devcontainer/devcontainer.json b/projects/.template/.devcontainer/devcontainer.json index 47ab620..76cd687 100644 --- a/projects/.template/.devcontainer/devcontainer.json +++ b/projects/.template/.devcontainer/devcontainer.json @@ -5,7 +5,7 @@ ], "name": "${localWorkspaceFolderBasename}", "overrideCommand": true, - "postCreateCommand": "sudo chown ${remoteUser} ${containerWorkspaceFolder}", + "postCreateCommand": "sudo chown $(id -un) ${containerWorkspaceFolder}", "service": "devcontainer", "workspaceFolder": "/mnt/${localWorkspaceFolderBasename}" } \ No newline at end of file