From 41ad420c72fabe95af152237f08ee8574c411704 Mon Sep 17 00:00:00 2001 From: QXYang686 Date: Sat, 14 Feb 2026 22:23:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=8F=91=E5=AE=B9=E5=99=A8=E9=85=8D?= =?UTF-8?q?=E7=BD=AE-=E5=88=9D=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common-base/.devcontainer/Dockerfile | 83 +++++++++++++++++++ common-base/.devcontainer/devcontainer.json | 38 +++++++++ develop-base/.devcontainer/Dockerfile | 4 + develop-base/.devcontainer/devcontainer.json | 12 +++ universal-base/.devcontainer/Dockerfile | 1 + .../.devcontainer/devcontainer.json | 66 +++++++++++++++ .../nvs/devcontainer-feature.json | 12 +++ .../local-features/nvs/install.sh | 79 ++++++++++++++++++ .../setup-user/devcontainer-feature.json | 29 +++++++ .../local-features/setup-user/install.sh | 44 ++++++++++ 10 files changed, 368 insertions(+) create mode 100644 common-base/.devcontainer/Dockerfile create mode 100644 common-base/.devcontainer/devcontainer.json create mode 100644 develop-base/.devcontainer/Dockerfile create mode 100644 develop-base/.devcontainer/devcontainer.json create mode 100644 universal-base/.devcontainer/Dockerfile create mode 100644 universal-base/.devcontainer/devcontainer.json create mode 100644 universal-base/.devcontainer/local-features/nvs/devcontainer-feature.json create mode 100644 universal-base/.devcontainer/local-features/nvs/install.sh create mode 100644 universal-base/.devcontainer/local-features/setup-user/devcontainer-feature.json create mode 100644 universal-base/.devcontainer/local-features/setup-user/install.sh diff --git a/common-base/.devcontainer/Dockerfile b/common-base/.devcontainer/Dockerfile new file mode 100644 index 0000000..1deecee --- /dev/null +++ b/common-base/.devcontainer/Dockerfile @@ -0,0 +1,83 @@ +FROM ubuntu:noble + +RUN if id "ubuntu" &>/dev/null; then \ + echo "Deleting user 'ubuntu' for noble" && userdel -f -r ubuntu || echo "Failed to delete ubuntu user for noble"; \ + else \ + echo "User 'ubuntu' does not exist for noble"; \ + fi + +ENV LANG="C.UTF-8" + +#Merging the mutiple layers to reduce the size of the image slightly +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + # Restore man command + && yes | unminimize 2>&1 \ + # Install basic build tools + && apt-get upgrade -y \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + make \ + unzip \ + # The tools in this package are used when installing packages for Python + build-essential \ + swig3.0 \ + # Required for Microsoft SQL Server + unixodbc-dev \ + # Required for PostgreSQL + libpq-dev \ + # Required for mysqlclient + default-libmysqlclient-dev \ + # Required for ts + moreutils \ + rsync \ + zip \ + libgdiplus \ + jq \ + # By default pip is not available in the buildpacks image + python3-pip \ + #.NET Core related pre-requisites + libc6 \ + libgcc1 \ + libgssapi-krb5-2 \ + libncurses6 \ + liblttng-ust1 \ + libssl-dev \ + libstdc++6 \ + zlib1g \ + libuuid1 \ + libunwind8 \ + sqlite3 \ + libsqlite3-dev \ + software-properties-common \ + tk-dev \ + uuid-dev \ + curl \ + gettext \ + inotify-tools \ + && rm -rf /var/lib/apt/lists/* \ + # This is the folder containing 'links' to benv and build script generator + && apt-get update \ + && apt-get upgrade -y \ + && add-apt-repository universe \ + && rm -rf /var/lib/apt/lists/* \ + # Verify expected build and debug tools are present + && apt-get update \ + && apt-get -y install build-essential cmake cppcheck valgrind clang lldb llvm gdb python3-dev \ + # Install tools and shells not in common script + && apt-get install -yq vim vim-doc xtail software-properties-common libsecret-1-dev \ + # Clean up + && apt-get autoremove -y && apt-get clean -y \ + # Move first run notice to right spot + && mkdir -p "/usr/local/etc/vscode-dev-containers/" \ + # Install and setup fish + && apt-get install -yq fish \ + && FISH_PROMPT="function fish_prompt\n set_color green\n echo -n (whoami)\n set_color normal\n echo -n \":\"\n set_color blue\n echo -n (pwd)\n set_color normal\n echo -n \"> \"\nend\n" \ + && printf "$FISH_PROMPT" >> /etc/fish/functions/fish_prompt.fish \ + && printf "if type code-insiders > /dev/null 2>&1; and not type code > /dev/null 2>&1\n alias code=code-insiders\nend" >> /etc/fish/conf.d/code_alias.fish \ + # Remove scripts now that we're done with them + && apt-get clean -y && rm -rf /tmp/scripts + +# Default to bash shell (other shells available at /usr/bin/fish and /usr/bin/zsh) +ENV SHELL=/bin/bash \ + DOCKER_BUILDKIT=1 + +CMD [ "sleep", "infinity" ] diff --git a/common-base/.devcontainer/devcontainer.json b/common-base/.devcontainer/devcontainer.json new file mode 100644 index 0000000..146caaa --- /dev/null +++ b/common-base/.devcontainer/devcontainer.json @@ -0,0 +1,38 @@ +{ + "build": { + "dockerfile": "./Dockerfile", + "context": ".", + }, + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "username": "codespace", + "userUid": "1000", + "userGid": "1000", + "configureZshAsDefaultShell": true, + }, + "ghcr.io/devcontainers/features/sshd:1": { + "gatewayPorts": "yes", + }, + "ghcr.io/devcontainers/features/desktop-lite:1": { + "password": "noPassword", + }, + }, + "remoteUser": "codespace", + "containerUser": "codespace", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "lldb.executable": "/usr/bin/lldb", + }, + // Add the IDs of extensions you want installed when the container is created. + "extensions": [], + }, + }, +} diff --git a/develop-base/.devcontainer/Dockerfile b/develop-base/.devcontainer/Dockerfile new file mode 100644 index 0000000..c4e8d95 --- /dev/null +++ b/develop-base/.devcontainer/Dockerfile @@ -0,0 +1,4 @@ +FROM registry.yqxpro.com/devcontainers/common-base + +# Mount for docker-in-docker +VOLUME [ "/var/lib/docker" ] diff --git a/develop-base/.devcontainer/devcontainer.json b/develop-base/.devcontainer/devcontainer.json new file mode 100644 index 0000000..00be2f8 --- /dev/null +++ b/develop-base/.devcontainer/devcontainer.json @@ -0,0 +1,12 @@ +{ + "build": { + "dockerfile": "./Dockerfile", + "context": ".", + }, + "features": { + "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/git-lfs:1": {}, + "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + "ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {}, + }, +} diff --git a/universal-base/.devcontainer/Dockerfile b/universal-base/.devcontainer/Dockerfile new file mode 100644 index 0000000..3efbf3e --- /dev/null +++ b/universal-base/.devcontainer/Dockerfile @@ -0,0 +1 @@ +FROM registry.yqxpro.com/devcontainers/develop-base diff --git a/universal-base/.devcontainer/devcontainer.json b/universal-base/.devcontainer/devcontainer.json new file mode 100644 index 0000000..f7771f5 --- /dev/null +++ b/universal-base/.devcontainer/devcontainer.json @@ -0,0 +1,66 @@ +{ + "build": { + "dockerfile": "./Dockerfile", + "context": ".", + }, + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "22", + "additionalVersions": "18,22,24", + }, + "./local-features/nvs": "latest", + "ghcr.io/devcontainers/features/python:1": { + "version": "3.12.1", + "installJupyterlab": "true", + "configureJupyterlabAllowOrigin": "*", + }, + "ghcr.io/devcontainers/features/anaconda:1": {}, + "ghcr.io/devcontainers/features/java:1": { + "jdkDistro": "tem", + "version": "21", + "additionalVersions": "8,21,25", + "installGradle": "true", + "installMaven": "true", + }, + "ghcr.io/devcontainers/features/go:1": {}, + "ghcr.io/devcontainers/features/rust:1": { + "profile": "complete", + }, + "./local-features/setup-user": "latest", + }, + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "go.toolsManagement.checkForUpdates": "local", + "go.useLanguageServer": true, + "go.gopath": "/go", + "python.defaultInterpreterPath": "/home/codespace/.python/current/bin/python3", + "jupyter.kernels.filter": [ + { + "path": "/opt/conda/bin/python", + "type": "pythonEnvironment", + }, + { + "path": "/usr/local/python/current/bin/python3", + "type": "pythonEnvironment", + }, + { + "path": "/usr/local/python/current/bin/python", + "type": "pythonEnvironment", + }, + { + "path": "/usr/bin/python3", + "type": "pythonEnvironment", + }, + { + "path": "/bin/python3", + "type": "pythonEnvironment", + }, + ], + }, + }, + }, +} diff --git a/universal-base/.devcontainer/local-features/nvs/devcontainer-feature.json b/universal-base/.devcontainer/local-features/nvs/devcontainer-feature.json new file mode 100644 index 0000000..610e683 --- /dev/null +++ b/universal-base/.devcontainer/local-features/nvs/devcontainer-feature.json @@ -0,0 +1,12 @@ +{ + "id": "nvs", + "name": "Node Version Switcher", + "containerEnv": { + "NVS_DIR": "/usr/local/nvs", + "PATH": "${NVS_DIR}:${PATH}" + }, + "install": { + "app": "", + "file": "install.sh" + } +} \ No newline at end of file diff --git a/universal-base/.devcontainer/local-features/nvs/install.sh b/universal-base/.devcontainer/local-features/nvs/install.sh new file mode 100644 index 0000000..9c2f1dc --- /dev/null +++ b/universal-base/.devcontainer/local-features/nvs/install.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- + +USERNAME=${USERNAME:-"codespace"} +NVS_HOME=${NVS_HOME:-"/usr/local/nvs"} + +set -eux + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Ensure that login shells get the correct path if the user updated the PATH using ENV. +rm -f /etc/profile.d/00-restore-env.sh +echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh +chmod +x /etc/profile.d/00-restore-env.sh + +# Function to run apt-get if needed +apt_get_update_if_needed() +{ + if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update + else + echo "Skipping apt-get update." + fi +} + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update_if_needed + apt-get -y install --no-install-recommends "$@" + fi +} + +updaterc() { + echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..." + if [[ "$(cat /etc/bash.bashrc)" != *"$1"* ]]; then + echo -e "$1" >> /etc/bash.bashrc + fi + if [ -f "/etc/zsh/zshrc" ] && [[ "$(cat /etc/zsh/zshrc)" != *"$1"* ]]; then + echo -e "$1" >> /etc/zsh/zshrc + fi +} + +export DEBIAN_FRONTEND=noninteractive + +if ! cat /etc/group | grep -e "^nvs:" > /dev/null 2>&1; then + groupadd -r nvs +fi +usermod -a -G nvs "${USERNAME}" + +git config --global --add safe.directory ${NVS_HOME} +mkdir -p ${NVS_HOME} + +git clone -c advice.detachedHead=false --depth 1 https://github.com/jasongin/nvs ${NVS_HOME} 2>&1 +(cd ${NVS_HOME} && git remote get-url origin && echo $(git log -n 1 --pretty=format:%H -- .)) > ${NVS_HOME}/.git-remote-and-commit +bash ${NVS_HOME}/nvs.sh install +rm ${NVS_HOME}/cache/* + +# Clean up +rm -rf ${NVS_HOME}/.git + +updaterc "if [[ \"\${PATH}\" != *\"${NVS_HOME}\"* ]]; then export PATH=${NVS_HOME}:\${PATH}; fi" + +chown -R "${USERNAME}:nvs" "${NVS_HOME}" +chmod -R g+r+w "${NVS_HOME}" +find "${NVS_HOME}" -type d | xargs -n 1 chmod g+s + +NVS="/home/codespace/.nvs" +mkdir -p ${NVS} +ln -snf ${NVS_HOME}/* $NVS + +echo "Done!" diff --git a/universal-base/.devcontainer/local-features/setup-user/devcontainer-feature.json b/universal-base/.devcontainer/local-features/setup-user/devcontainer-feature.json new file mode 100644 index 0000000..334512a --- /dev/null +++ b/universal-base/.devcontainer/local-features/setup-user/devcontainer-feature.json @@ -0,0 +1,29 @@ +{ + "id": "setup-user", + "name": "Setup user configs", + "containerEnv": { + "JAVA_ROOT": "/home/codespace/java", + "NODE_ROOT": "/home/codespace/nvm", + "PYTHON_ROOT": "/home/codespace/.python", + "MAVEN_ROOT": "/home/codespace/.maven", + "PYTHONIOENCODING": "UTF-8", + "NPM_GLOBAL": "/home/codespace/.npm-global", + "NVS_HOME": "/home/codespace/.nvs", + "GOROOT": "/usr/local/go", + "JUPYTERLAB_PATH": "/home/codespace/.local/bin", + "PATH": "/home/codespace/nvm/current/bin:/home/codespace/.python/current/bin:/home/codespace/java/current/bin:/home/codespace/.local/bin:${PATH}" + }, + "install": { + "app": "", + "file": "install.sh" + }, + "installsAfter": [ + "ghcr.io/devcontainers/features/node:1", + "./local-features/nvs", + "ghcr.io/devcontainers/features/python:1", + "ghcr.io/devcontainers/features/anaconda:1", + "ghcr.io/devcontainers/features/java:1", + "ghcr.io/devcontainers/features/go:1", + "ghcr.io/devcontainers/features/rust:1" + ] +} diff --git a/universal-base/.devcontainer/local-features/setup-user/install.sh b/universal-base/.devcontainer/local-features/setup-user/install.sh new file mode 100644 index 0000000..2350338 --- /dev/null +++ b/universal-base/.devcontainer/local-features/setup-user/install.sh @@ -0,0 +1,44 @@ +USERNAME=${USERNAME:-"codespace"} + +set -eux + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Ensure that login shells get the correct path if the user updated the PATH using ENV. +rm -f /etc/profile.d/00-restore-env.sh +touch /etc/profile.d/00-restore-env.sh # 暂时把有问题的替换忽略 +# echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh +chmod +x /etc/profile.d/00-restore-env.sh + +export DEBIAN_FRONTEND=noninteractive + +sudo_if() { + COMMAND="$*" + if [ "$(id -u)" -eq 0 ] && [ "$USERNAME" != "root" ]; then + su - "$USERNAME" -c "$COMMAND" + else + "$COMMAND" + fi +} + +NODE_PATH="/home/codespace/nvm/current" +ln -snf /usr/local/share/nvm /home/codespace + +PYTHON_PATH="/home/${USERNAME}/.python/current" +mkdir -p /home/${USERNAME}/.python +ln -snf /usr/local/python/current $PYTHON_PATH +ln -snf /usr/local/python /opt/python + +JAVA_PATH="/home/codespace/java/current" +ln -snf /usr/local/sdkman/candidates/java /home/codespace + +MAVEN_PATH="/home/${USERNAME}/.maven/current" +mkdir -p /home/${USERNAME}/.maven +ln -snf /usr/local/sdkman/candidates/maven/current $MAVEN_PATH + +echo "Defaults secure_path=\"${NODE_PATH}/bin:${PYTHON_PATH}/bin:${JAVA_PATH}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin:/usr/local/share:/home/${USERNAME}/.local/bin:${PATH}\"" >> /etc/sudoers.d/$USERNAME + +echo "Done!"