chore: update devcontainer configuration and add setup scripts
This commit is contained in:
@@ -1,100 +0,0 @@
|
|||||||
# docker build -t my-dev-container .
|
|
||||||
FROM debian:13.1-slim
|
|
||||||
|
|
||||||
# 元数据
|
|
||||||
LABEL maintainer="i@oo1.dev" \
|
|
||||||
description="Development container for Claude and Gemini development"
|
|
||||||
|
|
||||||
# 构建参数
|
|
||||||
ARG GIT_DELTA_VERSION=0.18.2
|
|
||||||
ARG ZSH_IN_DOCKER_VERSION=1.2.1
|
|
||||||
ARG TZ=Asia/Shanghai
|
|
||||||
|
|
||||||
# 环境变量
|
|
||||||
ENV PNPM_HOME="/home/usr_vscode/.local/share/pnpm"
|
|
||||||
ENV PATH="$PNPM_HOME:$PATH"
|
|
||||||
ENV LANG=zh_CN.UTF-8 \
|
|
||||||
LC_ALL=zh_CN.UTF-8 \
|
|
||||||
TZ=${TZ} \
|
|
||||||
# Set the default shell to zsh rather than sh
|
|
||||||
SHELL=/bin/zsh \
|
|
||||||
# Set the default editor and visual
|
|
||||||
EDITOR=nano \
|
|
||||||
VISUAL=nano \
|
|
||||||
POWERLEVEL9K_DISABLE_GITSTATUS=true
|
|
||||||
|
|
||||||
# 安装所有系统依赖
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
# 语言包
|
|
||||||
locales \
|
|
||||||
# 基础工具
|
|
||||||
ca-certificates wget curl \
|
|
||||||
# 开发工具
|
|
||||||
less git procps sudo fzf zsh man-db unzip gnupg2 gh \
|
|
||||||
# 网络工具
|
|
||||||
iptables ipset iproute2 dnsutils aggregate \
|
|
||||||
# 编辑器和实用工具
|
|
||||||
jq nano vim \
|
|
||||||
# 配置中文环境
|
|
||||||
&& sed -i 's/^# *zh_CN.UTF-8/zh_CN.UTF-8/' /etc/locale.gen \
|
|
||||||
&& locale-gen zh_CN.UTF-8 \
|
|
||||||
&& update-locale LANG=zh_CN.UTF-8 \
|
|
||||||
# 清理缓存
|
|
||||||
&& apt-get clean \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# 创建用户和配置 sudo
|
|
||||||
RUN groupadd --gid 1000 usr_vscode \
|
|
||||||
&& useradd --uid 1000 --gid usr_vscode --shell /bin/zsh --create-home usr_vscode \
|
|
||||||
&& echo "usr_vscode ALL=(root) NOPASSWD: ALL" > /etc/sudoers.d/usr_vscode_user_config \
|
|
||||||
&& chmod 0440 /etc/sudoers.d/usr_vscode_user_config \
|
|
||||||
&& cat /etc/passwd
|
|
||||||
|
|
||||||
# 配置命令历史
|
|
||||||
RUN mkdir -p /commandhistory \
|
|
||||||
&& touch /commandhistory/.bash_history \
|
|
||||||
&& chown -R usr_vscode:usr_vscode /commandhistory
|
|
||||||
|
|
||||||
# 创建工作目录
|
|
||||||
RUN mkdir -p /wrkspc /home/usr_vscode/.claude \
|
|
||||||
&& chown -R usr_vscode:usr_vscode /wrkspc /home/usr_vscode/.claude
|
|
||||||
|
|
||||||
# 安装 git-delta https://github.com/dandavison/delta/releases
|
|
||||||
RUN ARCH=$(dpkg --print-architecture) && \
|
|
||||||
curl -L -o "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
|
|
||||||
sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
|
|
||||||
rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"
|
|
||||||
|
|
||||||
WORKDIR /wrkspc
|
|
||||||
|
|
||||||
# 切换到非 root 用户
|
|
||||||
USER usr_vscode
|
|
||||||
|
|
||||||
# 配置 Zsh https://github.com/deluan/zsh-in-docker/releases
|
|
||||||
# Default powerline10k theme
|
|
||||||
RUN sh -c "$(curl -L -o - https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" -- \
|
|
||||||
-p git \
|
|
||||||
-p fzf \
|
|
||||||
-a "source <(fzf --zsh)" \
|
|
||||||
-a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
|
|
||||||
-x \
|
|
||||||
# -a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \
|
|
||||||
# -a "source /usr/share/doc/fzf/examples/completion.zsh" \
|
|
||||||
# https://github.com/deluan/zsh-in-docker/blob/55a4e476f78f37204af9dfc0290a92e52cf881b1/zsh-in-docker.sh#L121-L123
|
|
||||||
&& sed -i 's/^export LANG=.*/export LANG="zh_CN.UTF-8"/' /home/usr_vscode/.zshrc \
|
|
||||||
&& sed -i 's/^export LANGUAGE=.*/export LANGUAGE="zh_CN:zh"/' /home/usr_vscode/.zshrc \
|
|
||||||
&& sed -i 's/^export LC_ALL=.*/export LC_ALL="zh_CN.UTF-8"/' /home/usr_vscode/.zshrc \
|
|
||||||
# >>>>>
|
|
||||||
&& echo "" >> /home/usr_vscode/.zshrc \
|
|
||||||
&& echo "alias gemini='gemini --yolo -m gemini-2.5-pro'" >> /home/usr_vscode/.zshrc \
|
|
||||||
&& echo "alias claude='claude --dangerously-skip-permissions'" >> /home/usr_vscode/.zshrc \
|
|
||||||
&& echo '# [[ "$TERM_PROGRAM" == "vscode" ]] && . "$(code --locate-shell-integration-path zsh)"' >> /home/usr_vscode/.zshrc
|
|
||||||
|
|
||||||
# 安装 pnpm
|
|
||||||
# https://pnpm.io/installation#in-a-docker-container
|
|
||||||
RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.zshrc" SHELL="$(which zsh)" zsh - \
|
|
||||||
&& pnpm --version \
|
|
||||||
&& mkdir /home/usr_vscode/.pnpm-store \
|
|
||||||
&& mkdir -p /home/usr_vscode/.cache/pnpm \
|
|
||||||
# /home/usr_vscode/.config/pnpm/rc
|
|
||||||
&& pnpm config --global set store-dir /home/usr_vscode/.pnpm-store
|
|
||||||
@@ -1,41 +1,31 @@
|
|||||||
/**
|
|
||||||
* 一些参考链接:
|
|
||||||
* https://containers.dev/implementors/json_reference/#variables-in-devcontainerjson
|
|
||||||
* https://code.claude.com/docs/zh-CN/devcontainer
|
|
||||||
* https://github.com/Kilo-Org/kilocode/blob/main/cli/Dockerfile
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
"name": "SBX",
|
"image": "ghcr.io/yanhao98/h-devcontainer:oncreatecommand.d",
|
||||||
"image": "my-dev-container",
|
"runArgs": ["--name=${localWorkspaceFolderBasename}-devcontainer"],
|
||||||
// "build": { "dockerfile": "Dockerfile", "args": {} },
|
|
||||||
"runArgs": [
|
|
||||||
// -----
|
|
||||||
// "--network=host",
|
|
||||||
// "--add-host=myservice.local:127.0.0.1",
|
|
||||||
// -----
|
|
||||||
// "--env-file",
|
|
||||||
// ".devcontainer/.env",
|
|
||||||
// -----
|
|
||||||
"--cap-add=NET_ADMIN",
|
|
||||||
"--cap-add=NET_RAW",
|
|
||||||
"--add-host=host.docker.internal:host-gateway",
|
|
||||||
"--name=${localWorkspaceFolderBasename}-devcontainer"
|
|
||||||
],
|
|
||||||
"forwardPorts": [4730, 4731], // vscode://settings/remote.localPortHost -> 默认只监听 localhost
|
"forwardPorts": [4730, 4731], // vscode://settings/remote.localPortHost -> 默认只监听 localhost
|
||||||
"portsAttributes": {
|
"portsAttributes": {
|
||||||
"4730": { "label": "开发服务器端口", "onAutoForward": "notify" },
|
"4730": { "label": "开发服务器端口", "onAutoForward": "notify" },
|
||||||
"4731": { "label": "预览服务器端口", "onAutoForward": "notify" }
|
"4731": { "label": "预览服务器端口", "onAutoForward": "notify" }
|
||||||
},
|
},
|
||||||
|
"remoteEnv": {
|
||||||
|
"ANTHROPIC_AUTH_TOKEN": "${localEnv:ANTHROPIC_AUTH_TOKEN}",
|
||||||
|
"ANTHROPIC_BASE_URL": "${localEnv:ANTHROPIC_BASE_URL}",
|
||||||
|
"GEMINI_API_KEY": "${localEnv:GEMINI_API_KEY}",
|
||||||
|
"GOOGLE_GEMINI_BASE_URL": "${localEnv:GOOGLE_GEMINI_BASE_URL}",
|
||||||
|
"PATH": "${containerEnv:PATH}:${containerWorkspaceFolder}/node_modules/.bin:${containerEnv:HOME}/.bun/bin:${containerEnv:HOME}/.bun/bin/bun-node-fallback-bin"
|
||||||
|
},
|
||||||
|
"containerEnv": {
|
||||||
|
"HOME": "/home/usr_vscode",
|
||||||
|
// "NODE_OPTIONS": "--max-old-space-size=4096",
|
||||||
|
"TZ": "${localEnv:TZ:Asia/Shanghai}"
|
||||||
|
},
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
// AI
|
// AI
|
||||||
"github.copilot-chat",
|
"github.copilot-chat",
|
||||||
"vicanent.gcmp",
|
|
||||||
"anthropic.claude-code",
|
"anthropic.claude-code",
|
||||||
"google.gemini-cli-vscode-ide-companion",
|
"google.gemini-cli-vscode-ide-companion",
|
||||||
"kilocode.kilo-code",
|
"vicanent.gcmp",
|
||||||
"alibaba-cloud.tongyi-lingma",
|
|
||||||
// >>>>>
|
// >>>>>
|
||||||
// "eamodio.gitlens",
|
// "eamodio.gitlens",
|
||||||
"tu6ge.naive-ui-intelligence",
|
"tu6ge.naive-ui-intelligence",
|
||||||
@@ -46,7 +36,6 @@
|
|||||||
"vue.volar",
|
"vue.volar",
|
||||||
// <<<<<
|
// <<<<<
|
||||||
// 代码质量 / 格式化 / Lint
|
// 代码质量 / 格式化 / Lint
|
||||||
"editorconfig.editorconfig",
|
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"stylelint.vscode-stylelint",
|
"stylelint.vscode-stylelint",
|
||||||
"oxc.oxc-vscode",
|
"oxc.oxc-vscode",
|
||||||
@@ -58,13 +47,14 @@
|
|||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": "explicit"
|
"source.fixAll.eslint": "explicit"
|
||||||
},
|
},
|
||||||
|
|
||||||
"chat.extensionUnification.enabled": true,
|
"chat.extensionUnification.enabled": true,
|
||||||
"chat.tools.terminal.autoApprove": { "/.*/": true },
|
"chat.tools.terminal.autoApprove": {
|
||||||
"chat.tools.terminal.ignoreDefaultAutoApproveRules": false,
|
"/.*/": true,
|
||||||
|
"git push": false
|
||||||
|
},
|
||||||
// * 尽管使用了“/.*/”,但有些还是会失败,因为有几个错误的默认值:
|
// * 尽管使用了“/.*/”,但有些还是会失败,因为有几个错误的默认值:
|
||||||
// * https://github.com/microsoft/vscode/issues/266651#issuecomment-3292581459
|
// * https://github.com/microsoft/vscode/issues/266651#issuecomment-3292581459
|
||||||
|
"chat.tools.terminal.ignoreDefaultAutoApproveRules": true,
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"tasks": [
|
||||||
@@ -72,24 +62,16 @@
|
|||||||
"type": "npm",
|
"type": "npm",
|
||||||
"script": "dev",
|
"script": "dev",
|
||||||
"label": "🚀 Dev: Run on Folder Open",
|
"label": "🚀 Dev: Run on Folder Open",
|
||||||
"detail": "启动开发服务器",
|
"runOptions": {
|
||||||
"runOptions": { "runOn": "folderOpen" },
|
"runOn": "folderOpen"
|
||||||
"problemMatcher": [],
|
},
|
||||||
"isBackground": true,
|
"isBackground": true,
|
||||||
"presentation": { "reveal": "always", "panel": "dedicated" },
|
"presentation": {
|
||||||
"group": { "kind": "build", "isDefault": false }
|
"panel": "dedicated"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"terminal.integrated.defaultProfile.linux": "💲zsh",
|
|
||||||
"terminal.integrated.profiles.linux": {
|
|
||||||
"💲zsh": {
|
|
||||||
"path": "zsh",
|
|
||||||
"icon": "terminal-cmd",
|
|
||||||
"overrideName": true,
|
|
||||||
"color": "terminal.ansiGreen"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// https://stackoverflow.com/questions/75708866/vscode-dev-container-fails-to-load-ms-vscode-js-debug-extension-correctly
|
// https://stackoverflow.com/questions/75708866/vscode-dev-container-fails-to-load-ms-vscode-js-debug-extension-correctly
|
||||||
// https://davidwesst.com/blog/missing-bootloader-in-vscode-devcontainer/
|
// https://davidwesst.com/blog/missing-bootloader-in-vscode-devcontainer/
|
||||||
/**
|
/**
|
||||||
@@ -100,62 +82,61 @@
|
|||||||
* Error: illegal value for flag --max-old-space-size=4096--max-old-space-size=4096 of type size_t
|
* Error: illegal value for flag --max-old-space-size=4096--max-old-space-size=4096 of type size_t
|
||||||
* 将其设置为 "disabled" 以规避该问题。
|
* 将其设置为 "disabled" 以规避该问题。
|
||||||
*/
|
*/
|
||||||
"debug.javascript.autoAttachFilter": "disabled"
|
// "debug.javascript.autoAttachFilter": "disabled",
|
||||||
|
"terminal.integrated.defaultProfile.linux": "💲zsh",
|
||||||
|
"terminal.integrated.profiles.linux": {
|
||||||
|
"💲zsh": {
|
||||||
|
"path": "zsh",
|
||||||
|
"icon": "terminal-cmd",
|
||||||
|
"overrideName": true,
|
||||||
|
"color": "terminal.ansiGreen"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"containerEnv": {
|
|
||||||
// "CLAUDE_CONFIG_DIR": "/home/usr_vscode/.claude",
|
|
||||||
"ANTHROPIC_AUTH_TOKEN": "${localEnv:ANTHROPIC_AUTH_TOKEN}",
|
|
||||||
"ANTHROPIC_BASE_URL": "${localEnv:ANTHROPIC_BASE_URL}",
|
|
||||||
"GEMINI_API_KEY": "${localEnv:GEMINI_API_KEY}",
|
|
||||||
"GOOGLE_GEMINI_BASE_URL": "${localEnv:GOOGLE_GEMINI_BASE_URL}",
|
|
||||||
"NODE_OPTIONS": "--max-old-space-size=4096",
|
|
||||||
"CLAUDE_CONFIG_DIR": "/home/usr_vscode/.claude",
|
|
||||||
"DEVCONTAINER": "true", // https://github.com/anthropics/claude-code/blob/1fe9e369a7c30805189cbbb72eb69c15ed4ec96b/.devcontainer/Dockerfile#L42
|
|
||||||
"SANDBOX": "sandbox-devcontainer", // gemini 显示这个。
|
|
||||||
"TZ": "${localEnv:TZ:Asia/Shanghai}"
|
|
||||||
},
|
|
||||||
"mounts": [
|
"mounts": [
|
||||||
"source=${localWorkspaceFolderBasename}---bashhistory,target=/commandhistory,type=volume",
|
{
|
||||||
"source=${localWorkspaceFolderBasename}---iflow,target=/home/usr_vscode/.iflow,type=volume",
|
// 不挂载可能会遇到:`Cannot run macOS (Mach-O) executable in Docker: Exec format error`
|
||||||
"source=${localWorkspaceFolderBasename}---gemini,target=/home/usr_vscode/.gemini,type=volume",
|
"type": "volume",
|
||||||
"source=${localWorkspaceFolderBasename}---claude-code-router,target=/home/usr_vscode/.claude-code-router,type=volume",
|
"source": "${localWorkspaceFolderBasename}-node_modules",
|
||||||
"source=${localWorkspaceFolderBasename}---claude-code,target=/home/usr_vscode/.claude,type=volume",
|
"target": "${containerWorkspaceFolder}/node_modules"
|
||||||
"source=${localWorkspaceFolderBasename}---pnpm-store,target=/home/usr_vscode/.pnpm-store,type=volume",
|
},
|
||||||
"source=${localWorkspaceFolderBasename}---cache-pnpm,target=/home/usr_vscode/.cache/pnpm,type=volume",
|
{
|
||||||
"source=${localWorkspaceFolderBasename}---node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume"
|
"type": "volume",
|
||||||
|
"source": "devcontainer-pnpm-store",
|
||||||
|
"target": "/home/usr_vscode/.pnpm-store"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "volume",
|
||||||
|
"source": "devcontainer-bun-install-cache",
|
||||||
|
"target": "/home/usr_vscode/.bun/install/cache"
|
||||||
|
// rm -rf ~/.bun/install/cache/*
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bind",
|
||||||
|
"source": "${localWorkspaceFolder}/.devcontainer/onCreateCommand.d",
|
||||||
|
"target": "/usr/local/etc/onCreateCommand.d"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
/**
|
/**
|
||||||
* 执行顺序总结
|
* 执行顺序总结
|
||||||
1. initializeCommand (本地主机)
|
1. initializeCommand (本地主机,容器创建前)
|
||||||
2. 容器创建
|
2. 容器创建
|
||||||
3. onCreateCommand (容器内,仅首次)
|
3. onCreateCommand (容器首次创建时执行一次)
|
||||||
4. updateContentCommand (容器内)
|
4. updateContentCommand ()
|
||||||
5. postCreateCommand (容器内)
|
5. postCreateCommand (每次容器启动时执行)
|
||||||
6. 容器启动
|
6. 容器启动
|
||||||
7. postStartCommand (容器内,每次启动)
|
7. postStartCommand (容器内,每次启动)
|
||||||
8. VS Code 附加到容器
|
8. VS Code 附加到容器
|
||||||
9. postAttachCommand (容器内,每次附加)
|
9. postAttachCommand (容器内,每次附加)
|
||||||
*/
|
*/
|
||||||
"initializeCommand": /* 本地执行(容器创建前) */ "echo '准备创建容器...'",
|
"initializeCommand": "echo '↘️ 准备创建容器...'; docker pull ghcr.io/yanhao98/h-devcontainer:oncreatecommand.d;",
|
||||||
"onCreateCommand": /* 容器内执行(仅首次创建) */ {
|
"onCreateCommand": "echo '↘️ 容器首次创建!'; /usr/local/bin/onCreateCommand.sh",
|
||||||
"setup-node": "pnpm env use lts --global",
|
"updateContentCommand": "echo '↘️ 容器内容已更新!'; zsh -c 'time pnpm install;'",
|
||||||
"fix-claude-code-router": "sudo chown -R usr_vscode /home/usr_vscode/.claude-code-router",
|
"postCreateCommand": "echo '↘️ 容器已创建!';",
|
||||||
"fix-claude": "sudo chown -R usr_vscode /home/usr_vscode/.claude",
|
"postStartCommand": "echo '↘️ 容器启动了!'",
|
||||||
"fix-gemini": "sudo chown -R usr_vscode /home/usr_vscode/.gemini",
|
"postAttachCommand": "echo '↘️ VS Code 已附加到容器!'; zsh -c 'source ~/.zshrc; echo \"$(date +%Y-%m-%dT%H:%M:%S%z) - Welcome to your Dev Container!\"';",
|
||||||
"fix-iflow": "sudo chown -R usr_vscode /home/usr_vscode/.iflow",
|
|
||||||
"fix-node_modules": "sudo chown usr_vscode node_modules"
|
|
||||||
},
|
|
||||||
"updateContentCommand": /* 容器内执行(创建后或内容更新) */ "pnpm install",
|
|
||||||
"postCreateCommand": /* 容器内执行(创建完成后) */ {
|
|
||||||
"install-global-cli": "pnpm install -g @google/gemini-cli@latest @anthropic-ai/claude-code@latest @musistudio/claude-code-router@latest @iflow-ai/iflow-cli@latest"
|
|
||||||
},
|
|
||||||
"postStartCommand": /* 容器内执行(每次启动) */ "echo '容器已启动!'",
|
|
||||||
"postAttachCommand": /* 容器内执行(每次附加) */ "echo '开发环境已就绪!${containerWorkspaceFolder}'",
|
|
||||||
// "updateRemoteUserUID": true,
|
|
||||||
"waitFor": "updateContentCommand",
|
"waitFor": "updateContentCommand",
|
||||||
// "workspaceMount": "source=${localWorkspaceFolder},target=/${localWorkspaceFolderBasename},type=bind,consistency=delegated",
|
|
||||||
// "workspaceFolder": "/${localWorkspaceFolderBasename}",
|
|
||||||
"remoteUser": "usr_vscode"
|
"remoteUser": "usr_vscode"
|
||||||
}
|
}
|
||||||
|
|||||||
32
.devcontainer/onCreateCommand.d/00-configure-locale
Executable file
32
.devcontainer/onCreateCommand.d/00-configure-locale
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/zsh -eu
|
||||||
|
|
||||||
|
run_sys() {
|
||||||
|
if [[ "$EUID" -ne 0 ]]; then
|
||||||
|
sudo "$@"
|
||||||
|
else
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! dpkg -s locales >/dev/null 2>&1; then
|
||||||
|
run_sys apt-get update -qq
|
||||||
|
run_sys DEBIAN_FRONTEND=noninteractive apt-get install -qq -y --no-install-recommends locales
|
||||||
|
fi
|
||||||
|
|
||||||
|
run_sys sed -i "s/^# *zh_CN.UTF-8/zh_CN.UTF-8/" /etc/locale.gen
|
||||||
|
if ! locale -a | grep -qi "^zh_CN\.utf8$"; then
|
||||||
|
run_sys locale-gen zh_CN.UTF-8
|
||||||
|
fi
|
||||||
|
|
||||||
|
zshrc="$HOME/.zshrc"
|
||||||
|
mkdir -p "${zshrc:h}"
|
||||||
|
touch "$zshrc"
|
||||||
|
|
||||||
|
if ! grep -q '^export LANG=zh_CN.UTF-8$' "$zshrc" 2>/dev/null; then
|
||||||
|
printf '\nexport LANG=zh_CN.UTF-8\n' >>"$zshrc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep -q '^export LC_ALL=zh_CN.UTF-8$' "$zshrc" 2>/dev/null; then
|
||||||
|
printf 'export LC_ALL=zh_CN.UTF-8\n' >>"$zshrc"
|
||||||
|
fi
|
||||||
|
run_sys update-locale LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8
|
||||||
3
.devcontainer/onCreateCommand.d/00-fix-permission
Executable file
3
.devcontainer/onCreateCommand.d/00-fix-permission
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/zsh -eu
|
||||||
|
|
||||||
|
sudo chown -R $(whoami):$(whoami) node_modules || true
|
||||||
36
.devcontainer/onCreateCommand.d/01-configure-zsh
Executable file
36
.devcontainer/onCreateCommand.d/01-configure-zsh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/zsh -eu
|
||||||
|
|
||||||
|
TARGET_USER="usr_vscode"
|
||||||
|
if [[ "$EUID" -eq 0 ]]; then
|
||||||
|
target_home="/home/${TARGET_USER}"
|
||||||
|
else
|
||||||
|
target_home="$HOME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
zshrc="${target_home}/.zshrc"
|
||||||
|
mkdir -p "${zshrc:h}"
|
||||||
|
touch "$zshrc"
|
||||||
|
|
||||||
|
vscode_marker='if [[ "$TERM_PROGRAM" == "vscode" ]]; then'
|
||||||
|
if ! grep -Fq "$vscode_marker" "$zshrc" 2>/dev/null; then
|
||||||
|
cat <<'EOF' >>"$zshrc"
|
||||||
|
|
||||||
|
if [[ "$TERM_PROGRAM" == "vscode" ]]; then
|
||||||
|
local vscode_executable
|
||||||
|
if command -v code >/dev/null 2>&1; then
|
||||||
|
vscode_executable="code"
|
||||||
|
elif command -v code-insiders >/dev/null 2>&1; then
|
||||||
|
vscode_executable="code-insiders"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$vscode_executable" ]; then
|
||||||
|
. "$($vscode_executable --locate-shell-integration-path zsh)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
alias_snippet="alias clean-node-modules='setopt rm_star_silent; rm -rf node_modules/.*; rm -rf node_modules/*'; unsetopt rm_star_silent"
|
||||||
|
if ! grep -Fqx -- "$alias_snippet" "$zshrc" 2>/dev/null; then
|
||||||
|
printf '\n%s\n' "$alias_snippet" >>"$zshrc"
|
||||||
|
fi
|
||||||
49
.devcontainer/onCreateCommand.d/10-00-install-bun
Executable file
49
.devcontainer/onCreateCommand.d/10-00-install-bun
Executable file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/zsh -eu
|
||||||
|
|
||||||
|
# >>>>> 一些参考资料
|
||||||
|
# https://github.com/oven-sh/bun/blob/277fc558e2039e3ab25ecebecc5a3f04c5c3199a/dockerhub/debian-slim/Dockerfile
|
||||||
|
# COPY --chown=usr_vscode:usr_vscode --from=oven/bun:1-debian /usr/local/bin/bun /usr/local/bin
|
||||||
|
# IS_BUN_AUTO_UPDATE=true SHELL=zsh bun completions
|
||||||
|
# bun install -g 将会安装到 ENV BUN_INSTALL_BIN
|
||||||
|
# ENV PATH "${BUN_INSTALL_BIN}:${PATH}"
|
||||||
|
# RUN sudo mkdir -p /usr/local/bun-node-fallback-bin && sudo ln -s /usr/local/bin/bun /usr/local/bun-node-fallback-bin/node
|
||||||
|
# ENV PATH "${PATH}:/usr/local/bun-node-fallback-bin"
|
||||||
|
# <<<<<
|
||||||
|
|
||||||
|
# fix permission
|
||||||
|
# 有可能这个目录是 volume 挂载过来的,权限会有问题。
|
||||||
|
sudo mkdir -p ~/.bun || true
|
||||||
|
sudo chown -R $(whoami):$(whoami) ~/.bun || true
|
||||||
|
|
||||||
|
curl -fsSL https://bun.com/install | bash
|
||||||
|
|
||||||
|
# https://bun.sh/docs/runtime/nodejs-compat
|
||||||
|
mkdir -p ~/.bun/bin/bun-node-fallback-bin || true
|
||||||
|
ln -sf ~/.bun/bin/bun ~/.bun/bin/bun-node-fallback-bin/node
|
||||||
|
|
||||||
|
which -a bun
|
||||||
|
bun --version
|
||||||
|
which -a bunx
|
||||||
|
bunx --version
|
||||||
|
which -a node
|
||||||
|
|
||||||
|
# >>>>> pnpm
|
||||||
|
bun add -g pnpm@latest
|
||||||
|
# echo "alias pnpm='bunx pnpm'" >> ~/.zshrc
|
||||||
|
# echo "alias pnpx='bunx pnpx'" >> ~/.zshrc
|
||||||
|
bunx pnpm config set store-dir ~/.pnpm-store
|
||||||
|
sudo chown -R $(whoami):$(whoami) ~/.pnpm-store || true
|
||||||
|
|
||||||
|
# >>>>> npm
|
||||||
|
bun add -g npm@latest
|
||||||
|
|
||||||
|
# >>>>> Claude Code 工具
|
||||||
|
bun add -g @anthropic-ai/claude-code@latest
|
||||||
|
echo "alias claude='bunx claude --dangerously-skip-permissions'" >> ~/.zshrc
|
||||||
|
# 参考: https://github.com/anthropics/claude-code/blob/1fe9e369a7c30805189cbbb72eb69c15ed4ec96b/.devcontainer/Dockerfile#L42
|
||||||
|
echo "export DEVCONTAINER=true" >> ~/.zshrc
|
||||||
|
|
||||||
|
# >>>>>> Gemini CLI 工具
|
||||||
|
bun add -g @google/gemini-cli@latest
|
||||||
|
echo "alias gemini='bunx -g gemini --yolo -m gemini-2.5-pro'" >> ~/.zshrc
|
||||||
|
echo "export SANDBOX=bun-devcontainer" >> ~/.zshrc
|
||||||
Reference in New Issue
Block a user