Spaces:
Running
Running
Upload 2 files
Browse files- Dockerfile +135 -0
- start.sh +172 -0
Dockerfile
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.14.3-slim-bookworm
|
| 2 |
+
|
| 3 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
| 4 |
+
ENV TZ=Etc/UTC
|
| 5 |
+
ENV PORT=7860
|
| 6 |
+
ENV HOME=/home/coder
|
| 7 |
+
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
|
| 8 |
+
ENV PYTHONDONTWRITEBYTECODE=1
|
| 9 |
+
ENV PYTHONUNBUFFERED=1
|
| 10 |
+
|
| 11 |
+
ARG CODE_SERVER_VERSION=4.109.2
|
| 12 |
+
ARG KOTLIN_VERSION=1.9.25
|
| 13 |
+
ARG ANDROID_CMDLINE_TOOLS_VERSION=11076708
|
| 14 |
+
ARG ANDROID_PLATFORM=34
|
| 15 |
+
ARG ANDROID_BUILD_TOOLS=34.0.0
|
| 16 |
+
ARG GO_VERSION=1.26.1
|
| 17 |
+
ARG NODE_VERSION=25.8.1
|
| 18 |
+
|
| 19 |
+
ENV KOTLIN_HOME=/opt/kotlin
|
| 20 |
+
ENV ANDROID_SDK_ROOT=/opt/android-sdk
|
| 21 |
+
ENV ANDROID_HOME=/opt/android-sdk
|
| 22 |
+
ENV GOROOT=/usr/local/go
|
| 23 |
+
ENV GOPATH=/home/coder/go
|
| 24 |
+
ENV PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright
|
| 25 |
+
ENV PATH="${PATH}:${KOTLIN_HOME}/bin:${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin:${ANDROID_SDK_ROOT}/platform-tools:${GOROOT}/bin:${GOPATH}/bin"
|
| 26 |
+
|
| 27 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 28 |
+
ca-certificates curl git bash sudo tini jq procps unzip gnupg xz-utils \
|
| 29 |
+
# C/C++ toolchain + headers
|
| 30 |
+
build-essential gcc g++ make cmake ninja-build gdb clang clangd \
|
| 31 |
+
libc6-dev linux-libc-dev pkg-config \
|
| 32 |
+
# Java
|
| 33 |
+
openjdk-17-jdk-headless maven \
|
| 34 |
+
# Databases
|
| 35 |
+
default-mysql-server default-mysql-client \
|
| 36 |
+
postgresql postgresql-client \
|
| 37 |
+
redis-server redis-tools \
|
| 38 |
+
# Rust + Go
|
| 39 |
+
rustc cargo rustfmt \
|
| 40 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 41 |
+
|
| 42 |
+
# Install code-server (pinned version)
|
| 43 |
+
RUN curl -fsSL "https://github.com/coder/code-server/releases/download/v${CODE_SERVER_VERSION}/code-server_${CODE_SERVER_VERSION}_amd64.deb" -o /tmp/code-server.deb \
|
| 44 |
+
&& dpkg -i /tmp/code-server.deb \
|
| 45 |
+
&& rm -f /tmp/code-server.deb
|
| 46 |
+
|
| 47 |
+
# Node.js (official tarball, pinned to the latest current release)
|
| 48 |
+
RUN curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" -o /tmp/node.tar.xz \
|
| 49 |
+
&& tar -xJf /tmp/node.tar.xz -C /usr/local --strip-components=1 \
|
| 50 |
+
&& rm -f /tmp/node.tar.xz \
|
| 51 |
+
&& node --version \
|
| 52 |
+
&& npm --version
|
| 53 |
+
|
| 54 |
+
# Docker Engine + CLI + Buildx + Compose (official Docker apt repo)
|
| 55 |
+
RUN install -m 0755 -d /etc/apt/keyrings \
|
| 56 |
+
&& curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \
|
| 57 |
+
&& chmod a+r /etc/apt/keyrings/docker.asc \
|
| 58 |
+
&& printf "Types: deb\nURIs: https://download.docker.com/linux/debian\nSuites: %s\nComponents: stable\nArchitectures: %s\nSigned-By: /etc/apt/keyrings/docker.asc\n" "$(. /etc/os-release && echo "$VERSION_CODENAME")" "$(dpkg --print-architecture)" > /etc/apt/sources.list.d/docker.sources \
|
| 59 |
+
&& apt-get update \
|
| 60 |
+
&& apt-get install -y --no-install-recommends docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin \
|
| 61 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 62 |
+
|
| 63 |
+
# Kotlin compiler
|
| 64 |
+
RUN curl -fsSL "https://github.com/JetBrains/kotlin/releases/download/v${KOTLIN_VERSION}/kotlin-compiler-${KOTLIN_VERSION}.zip" -o /tmp/kotlin.zip \
|
| 65 |
+
&& unzip -q /tmp/kotlin.zip -d /opt \
|
| 66 |
+
&& mv /opt/kotlinc "${KOTLIN_HOME}" \
|
| 67 |
+
&& ln -s "${KOTLIN_HOME}/bin/kotlin" /usr/local/bin/kotlin \
|
| 68 |
+
&& ln -s "${KOTLIN_HOME}/bin/kotlinc" /usr/local/bin/kotlinc \
|
| 69 |
+
&& rm -f /tmp/kotlin.zip
|
| 70 |
+
|
| 71 |
+
# Go (official tarball for newer version than Debian repos)
|
| 72 |
+
RUN curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -o /tmp/go.tgz \
|
| 73 |
+
&& rm -rf /usr/local/go \
|
| 74 |
+
&& tar -C /usr/local -xzf /tmp/go.tgz \
|
| 75 |
+
&& rm -f /tmp/go.tgz
|
| 76 |
+
|
| 77 |
+
# Android SDK command-line tools + common packages
|
| 78 |
+
RUN mkdir -p "${ANDROID_SDK_ROOT}/cmdline-tools" \
|
| 79 |
+
&& curl -fsSL "https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_CMDLINE_TOOLS_VERSION}_latest.zip" -o /tmp/android-tools.zip \
|
| 80 |
+
&& unzip -q /tmp/android-tools.zip -d "${ANDROID_SDK_ROOT}/cmdline-tools" \
|
| 81 |
+
&& mv "${ANDROID_SDK_ROOT}/cmdline-tools/cmdline-tools" "${ANDROID_SDK_ROOT}/cmdline-tools/latest" \
|
| 82 |
+
&& rm -f /tmp/android-tools.zip \
|
| 83 |
+
&& yes | "${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager" --sdk_root="${ANDROID_SDK_ROOT}" --licenses \
|
| 84 |
+
&& "${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager" --sdk_root="${ANDROID_SDK_ROOT}" \
|
| 85 |
+
"platform-tools" "platforms;android-${ANDROID_PLATFORM}" "build-tools;${ANDROID_BUILD_TOOLS}"
|
| 86 |
+
|
| 87 |
+
# Python core deps
|
| 88 |
+
RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \
|
| 89 |
+
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 pip install --no-cache-dir \
|
| 90 |
+
numpy pandas scipy scikit-learn matplotlib \
|
| 91 |
+
jupyterlab ipykernel notebook \
|
| 92 |
+
requests httpx aiohttp pyyaml python-dotenv tqdm rich \
|
| 93 |
+
fastapi uvicorn[standard] pydantic flask \
|
| 94 |
+
sqlalchemy alembic psycopg2-binary redis \
|
| 95 |
+
pytest black isort ruff mypy \
|
| 96 |
+
playwright
|
| 97 |
+
|
| 98 |
+
# Codex CLI + Playwright + Playwright MCP
|
| 99 |
+
# Remove pip-installed playwright CLI to avoid npm binary conflict
|
| 100 |
+
RUN rm -f /usr/local/bin/playwright \
|
| 101 |
+
&& npm install -g @openai/codex playwright @playwright/mcp \
|
| 102 |
+
&& npm cache clean --force
|
| 103 |
+
|
| 104 |
+
# Playwright browsers + system deps (Chromium/Firefox/WebKit)
|
| 105 |
+
RUN mkdir -p "${PLAYWRIGHT_BROWSERS_PATH}" \
|
| 106 |
+
&& playwright install --with-deps
|
| 107 |
+
|
| 108 |
+
# Create user
|
| 109 |
+
RUN groupadd -f docker \
|
| 110 |
+
&& useradd -m -u 1000 -s /bin/bash -G docker coder \
|
| 111 |
+
&& echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \
|
| 112 |
+
&& mkdir -p /home/coder/.config/code-server /home/coder/.codex /home/coder/go \
|
| 113 |
+
&& chown -R coder:coder /home/coder /opt/kotlin /opt/android-sdk /opt/ms-playwright
|
| 114 |
+
|
| 115 |
+
# Quick toolchain checks (build-time)
|
| 116 |
+
RUN printf '#include <stdio.h>\nint main(){puts("ok");return 0;}\n' > /tmp/t.c \
|
| 117 |
+
&& gcc /tmp/t.c -o /tmp/t \
|
| 118 |
+
&& /tmp/t | grep -q ok \
|
| 119 |
+
&& python --version \
|
| 120 |
+
&& node --version \
|
| 121 |
+
&& npm --version \
|
| 122 |
+
&& docker --version \
|
| 123 |
+
&& docker buildx version \
|
| 124 |
+
&& docker compose version \
|
| 125 |
+
&& rm -f /tmp/t.c /tmp/t
|
| 126 |
+
|
| 127 |
+
COPY --chown=coder:coder start.sh /usr/local/bin/start.sh
|
| 128 |
+
RUN chmod +x /usr/local/bin/start.sh
|
| 129 |
+
|
| 130 |
+
USER coder
|
| 131 |
+
WORKDIR /home/coder
|
| 132 |
+
|
| 133 |
+
EXPOSE 7860
|
| 134 |
+
ENTRYPOINT ["/usr/bin/tini", "--"]
|
| 135 |
+
CMD ["/usr/local/bin/start.sh"]
|
start.sh
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
PORT="${PORT:-7860}"
|
| 5 |
+
|
| 6 |
+
if [[ -z "${PASSWORD:-}" && -z "${HASHED_PASSWORD:-}" ]]; then
|
| 7 |
+
echo "[ERROR] Missing PASSWORD/HASHED_PASSWORD secret."
|
| 8 |
+
exit 1
|
| 9 |
+
fi
|
| 10 |
+
|
| 11 |
+
if [[ -d "/data" ]]; then
|
| 12 |
+
WORKDIR="/data/workspace"
|
| 13 |
+
EXT_DIR="/data/code-server/extensions"
|
| 14 |
+
USER_DATA_DIR="/data/code-server/user-data"
|
| 15 |
+
CODEX_DIR="/data/.codex"
|
| 16 |
+
else
|
| 17 |
+
WORKDIR="${HOME}/workspace"
|
| 18 |
+
EXT_DIR="${HOME}/.local/share/code-server/extensions"
|
| 19 |
+
USER_DATA_DIR="${HOME}/.local/share/code-server/user-data"
|
| 20 |
+
CODEX_DIR="${HOME}/.codex"
|
| 21 |
+
fi
|
| 22 |
+
|
| 23 |
+
mkdir -p "$WORKDIR" "$EXT_DIR" "$USER_DATA_DIR" "${USER_DATA_DIR}/User" "${HOME}/.config/code-server" "$CODEX_DIR"
|
| 24 |
+
|
| 25 |
+
cat > "${HOME}/.config/code-server/config.yaml" <<EOF
|
| 26 |
+
bind-addr: 0.0.0.0:${PORT}
|
| 27 |
+
auth: password
|
| 28 |
+
cert: false
|
| 29 |
+
EOF
|
| 30 |
+
|
| 31 |
+
if [[ -n "${HASHED_PASSWORD:-}" ]]; then
|
| 32 |
+
echo "hashed-password: ${HASHED_PASSWORD}" >> "${HOME}/.config/code-server/config.yaml"
|
| 33 |
+
else
|
| 34 |
+
echo "password: ${PASSWORD}" >> "${HOME}/.config/code-server/config.yaml"
|
| 35 |
+
fi
|
| 36 |
+
|
| 37 |
+
# Codex config.toml
|
| 38 |
+
: "${CODEX_MODEL_PROVIDER:=sub2api}"
|
| 39 |
+
: "${CODEX_MODEL:=gpt-5.2-codex}"
|
| 40 |
+
: "${CODEX_REASONING_EFFORT:=xhigh}"
|
| 41 |
+
: "${CODEX_NETWORK_ACCESS:=enabled}"
|
| 42 |
+
: "${CODEX_DISABLE_RESPONSE_STORAGE:=true}"
|
| 43 |
+
: "${CODEX_WSL_ACK:=true}"
|
| 44 |
+
: "${CODEX_VERBOSITY:=high}"
|
| 45 |
+
: "${CODEX_PROVIDER_NAME:=sub2api}"
|
| 46 |
+
: "${CODEX_BASE_URL:=https://cacode-sub2api-dev.hf.space}"
|
| 47 |
+
: "${CODEX_WIRE_API:=responses}"
|
| 48 |
+
: "${CODEX_REQUIRES_OPENAI_AUTH:=true}"
|
| 49 |
+
: "${PLAYWRIGHT_MCP_ENABLE:=true}"
|
| 50 |
+
: "${PLAYWRIGHT_MCP_HOST:=127.0.0.1}"
|
| 51 |
+
: "${PLAYWRIGHT_MCP_PORT:=8931}"
|
| 52 |
+
: "${PLAYWRIGHT_MCP_URL:=http://${PLAYWRIGHT_MCP_HOST}:${PLAYWRIGHT_MCP_PORT}/mcp}"
|
| 53 |
+
|
| 54 |
+
cat > "${CODEX_DIR}/config.toml" <<EOF
|
| 55 |
+
model_provider = "${CODEX_MODEL_PROVIDER}"
|
| 56 |
+
model = "${CODEX_MODEL}"
|
| 57 |
+
model_reasoning_effort = "${CODEX_REASONING_EFFORT}"
|
| 58 |
+
network_access = "${CODEX_NETWORK_ACCESS}"
|
| 59 |
+
disable_response_storage = ${CODEX_DISABLE_RESPONSE_STORAGE}
|
| 60 |
+
windows_wsl_setup_acknowledged = ${CODEX_WSL_ACK}
|
| 61 |
+
model_verbosity = "${CODEX_VERBOSITY}"
|
| 62 |
+
|
| 63 |
+
[model_providers.${CODEX_PROVIDER_NAME}]
|
| 64 |
+
name = "${CODEX_PROVIDER_NAME}"
|
| 65 |
+
base_url = "${CODEX_BASE_URL}"
|
| 66 |
+
wire_api = "${CODEX_WIRE_API}"
|
| 67 |
+
requires_openai_auth = ${CODEX_REQUIRES_OPENAI_AUTH}
|
| 68 |
+
EOF
|
| 69 |
+
|
| 70 |
+
if [[ "${PLAYWRIGHT_MCP_ENABLE}" == "true" ]]; then
|
| 71 |
+
cat >> "${CODEX_DIR}/config.toml" <<EOF
|
| 72 |
+
|
| 73 |
+
[mcp_servers.playwright]
|
| 74 |
+
url = "${PLAYWRIGHT_MCP_URL}"
|
| 75 |
+
EOF
|
| 76 |
+
fi
|
| 77 |
+
|
| 78 |
+
if [[ -n "${CODEX_AUTH_JSON:-}" ]]; then
|
| 79 |
+
printf '%s\n' "${CODEX_AUTH_JSON}" > "${CODEX_DIR}/auth.json"
|
| 80 |
+
elif [[ -n "${OPENAI_API_KEY:-}" ]]; then
|
| 81 |
+
cat > "${CODEX_DIR}/auth.json" <<EOF
|
| 82 |
+
{
|
| 83 |
+
"OPENAI_API_KEY": "${OPENAI_API_KEY}"
|
| 84 |
+
}
|
| 85 |
+
EOF
|
| 86 |
+
fi
|
| 87 |
+
|
| 88 |
+
chmod 600 "${CODEX_DIR}/config.toml" 2>/dev/null || true
|
| 89 |
+
chmod 600 "${CODEX_DIR}/auth.json" 2>/dev/null || true
|
| 90 |
+
|
| 91 |
+
if [[ "${CODEX_DIR}" != "${HOME}/.codex" ]]; then
|
| 92 |
+
rm -rf "${HOME}/.codex"
|
| 93 |
+
ln -s "${CODEX_DIR}" "${HOME}/.codex"
|
| 94 |
+
fi
|
| 95 |
+
|
| 96 |
+
# 默认中文界面
|
| 97 |
+
cat > "${USER_DATA_DIR}/User/locale.json" <<EOF
|
| 98 |
+
{
|
| 99 |
+
"locale": "zh-cn"
|
| 100 |
+
}
|
| 101 |
+
EOF
|
| 102 |
+
|
| 103 |
+
# 首次启动安装扩展(幂等)
|
| 104 |
+
EXT_MARKER="${USER_DATA_DIR}/.extensions_installed"
|
| 105 |
+
if [[ ! -f "${EXT_MARKER}" ]]; then
|
| 106 |
+
echo "[INFO] Installing extensions on first boot..."
|
| 107 |
+
|
| 108 |
+
install_ext() {
|
| 109 |
+
code-server --extensions-dir "${EXT_DIR}" --install-extension "$1" || true
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
# 你指定的 3 个(尽量装)
|
| 113 |
+
install_ext ms-vscode.cpptools
|
| 114 |
+
install_ext ms-vscode.cpptools-themes
|
| 115 |
+
install_ext ms-vscode.cpp-devtools
|
| 116 |
+
install_ext ms-vscode.cmake-tools
|
| 117 |
+
install_ext danielpinto8zz6.c-cpp-compile-run
|
| 118 |
+
install_ext golang.go
|
| 119 |
+
install_ext rust-lang.rust-analyzer
|
| 120 |
+
install_ext redhat.java
|
| 121 |
+
install_ext vscjava.vscode-java-debug
|
| 122 |
+
install_ext vscjava.vscode-java-test
|
| 123 |
+
install_ext vscjava.vscode-maven
|
| 124 |
+
install_ext vscjava.vscode-gradle
|
| 125 |
+
install_ext vscjava.vscode-java-dependency
|
| 126 |
+
install_ext ms-python.vscode-pylance
|
| 127 |
+
install_ext ms-python.python
|
| 128 |
+
install_ext ms-python.debugpy
|
| 129 |
+
install_ext ms-python.vscode-python-envs
|
| 130 |
+
install_ext ms-playwright.playwright
|
| 131 |
+
|
| 132 |
+
# Codex
|
| 133 |
+
install_ext openai.chatgpt
|
| 134 |
+
|
| 135 |
+
# 若微软扩展不可用,装稳定替代
|
| 136 |
+
install_ext MS-CEINTL.vscode-language-pack-zh-hans
|
| 137 |
+
install_ext llvm-vs-code-extensions.vscode-clangd
|
| 138 |
+
install_ext ms-vscode.makefile-tools
|
| 139 |
+
install_ext vadimcn.vscode-lldb
|
| 140 |
+
|
| 141 |
+
touch "${EXT_MARKER}"
|
| 142 |
+
fi
|
| 143 |
+
|
| 144 |
+
if [[ "${PLAYWRIGHT_MCP_ENABLE}" == "true" ]]; then
|
| 145 |
+
if command -v playwright-mcp >/dev/null 2>&1; then
|
| 146 |
+
echo "[INFO] Starting Playwright MCP server at ${PLAYWRIGHT_MCP_URL}"
|
| 147 |
+
nohup playwright-mcp --headless --browser chromium --no-sandbox --port "${PLAYWRIGHT_MCP_PORT}" --host "${PLAYWRIGHT_MCP_HOST}" >/tmp/playwright-mcp.log 2>&1 &
|
| 148 |
+
else
|
| 149 |
+
echo "[WARN] Playwright MCP not installed; skipping server start."
|
| 150 |
+
fi
|
| 151 |
+
fi
|
| 152 |
+
|
| 153 |
+
echo "[INFO] Java: $(java -version 2>&1 | head -n1 || true)"
|
| 154 |
+
echo "[INFO] Python: $(python --version || true)"
|
| 155 |
+
echo "[INFO] Pip: $(pip --version || true)"
|
| 156 |
+
echo "[INFO] Node: $(node --version || true)"
|
| 157 |
+
echo "[INFO] npm: $(npm --version || true)"
|
| 158 |
+
echo "[INFO] Docker: $(docker --version || true)"
|
| 159 |
+
echo "[INFO] Buildx: $(docker buildx version 2>/dev/null || true)"
|
| 160 |
+
echo "[INFO] Compose: $(docker compose version 2>/dev/null || true)"
|
| 161 |
+
echo "[INFO] g++: $(g++ --version | head -n1 || true)"
|
| 162 |
+
echo "[INFO] Rust: $(rustc --version || true)"
|
| 163 |
+
echo "[INFO] Cargo: $(cargo --version || true)"
|
| 164 |
+
echo "[INFO] Go: $(go version || true)"
|
| 165 |
+
echo "[INFO] Playwright: $(playwright --version 2>/dev/null || true)"
|
| 166 |
+
|
| 167 |
+
exec code-server "$WORKDIR" \
|
| 168 |
+
--extensions-dir "$EXT_DIR" \
|
| 169 |
+
--user-data-dir "$USER_DATA_DIR" \
|
| 170 |
+
--disable-telemetry \
|
| 171 |
+
--disable-update-check \
|
| 172 |
+
--log warn
|