From 5d5a09419676fec7ceda16c386e7f438adbf8525 Mon Sep 17 00:00:00 2001 From: meowrain Date: Mon, 16 Feb 2026 00:44:57 +0800 Subject: [PATCH] feat(lsp): add Python language server support - Add pyright-langserver for Python LSP support - Add environment variable overrides for Python LSP configuration - Install git in Docker image (required for gopls dependency resolution) - Optimize Go binary build with -s -w linker flags for smaller image - Add GOPROXY configuration for faster dependency downloads - Update Node.js installation method with GPG key verification - Add entrypoint script to auto-create go.mod in workspace - Add /app/logs volume for log persistence --- backend/Dockerfile | 67 ++++++++++++++++++++++++------------- backend/cmd/server/main.go | 7 ++++ backend/config.example.json | 8 +++++ backend/config.json | 8 +++++ 4 files changed, 66 insertions(+), 24 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index e301b6b..e01ec48 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,10 +1,4 @@ # syntax=docker/dockerfile:1 -############################################################################### -# All-in-one LSP Gateway Image -# - Go → gopls -# - JS / TS → typescript-language-server -# - Java → Eclipse JDT Language Server (jdtls) + JDK 22 -############################################################################### # ── Stage 1: Build Go gateway binary ──────────────────────────────────────── FROM golang:1.25-bookworm AS builder @@ -12,46 +6,64 @@ WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . +# 优化:去除符号表(-s -w)减小体积,CGO_ENABLED=0 确保静态链接 RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/server ./cmd/server # ── Stage 2: Build gopls ──────────────────────────────────────────────────── FROM golang:1.25-bookworm AS gopls-builder -RUN go install golang.org/x/tools/gopls@latest +# 优化:静态编译 gopls,避免 GLIBC 版本依赖问题 +RUN CGO_ENABLED=0 go install golang.org/x/tools/gopls@latest # ── Stage 3: Runtime ──────────────────────────────────────────────────────── FROM eclipse-temurin:22-jdk-noble ARG NODE_MAJOR=22 -# ---- System deps: Node.js, python3 (jdtls launcher) ---- +# ---- System deps ---- +# 🔴 关键修复:必须安装 git,否则 gopls 无法拉取依赖 +# python3: JDTLS 需要 +# nodejs: TS Server 需要 RUN apt-get update && \ - apt-get install -y --no-install-recommends ca-certificates curl python3 && \ - curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + python3 \ + git \ + gnupg && \ + mkdir -p /etc/apt/keyrings && \ + curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ + apt-get update && \ apt-get install -y --no-install-recommends nodejs && \ + apt-get clean && \ rm -rf /var/lib/apt/lists/* -# ---- typescript-language-server (covers JavaScript + TypeScript) ---- -RUN npm install -g typescript-language-server typescript && \ +# ---- typescript-language-server + pyright (Python LSP) ---- +RUN npm install -g typescript-language-server typescript pyright && \ npm cache clean --force -# ---- Go toolchain (gopls needs it at runtime for analysis) ---- +# ---- Go toolchain (Optimized) ---- COPY --from=golang:1.25-bookworm /usr/local/go /usr/local/go + + +# 🟡 建议:设置 GOPROXY 加速依赖下载 (gopls 需要) ENV PATH="/usr/local/go/bin:/go/bin:${PATH}" \ - GOPATH="/go" + GOPATH="/go" \ + GOPROXY="https://goproxy.io,direct" # ---- gopls ---- COPY --from=gopls-builder /go/bin/gopls /go/bin/gopls # ---- Eclipse JDT Language Server ---- +# !!! 请确保当前目录下有这个文件夹 !!! COPY jdt-language-server-1.57.0-202602111032 /opt/jdtls RUN chmod +x /opt/jdtls/bin/jdtls /opt/jdtls/bin/jdtls.py -# ---- Gateway binary ---- +# ---- Gateway Setup ---- WORKDIR /app COPY --from=builder /out/server /app/server -COPY config.example.json /app/config.example.json -# ---- Default config: all 4 LSP servers, Redis/Nacos off by default ---- +# ---- 默认配置 ---- COPY <<'EOF' /app/config.json { "port": "8080", @@ -62,28 +74,35 @@ COPY <<'EOF' /app/config.json "cleanupInterval": "2m", "maxSessions": 256, "enableRedis": false, - "enableNacosRegister": false, "appEnv": "prod", "logLevel": "info", "logConsoleEnabled": true, + "logDir": "/app/logs", "servers": [ - { "language": "go", "languageId": "go", "command": "gopls", "args": [] }, + { "language": "go", "languageId": "go", "command": "gopls", "args": [] }, { "language": "javascript", "languageId": "javascript", "command": "typescript-language-server", "args": ["--stdio"] }, { "language": "typescript", "languageId": "typescript", "command": "typescript-language-server", "args": ["--stdio"] }, - { "language": "java", "languageId": "java", "command": "/opt/jdtls/bin/jdtls", "args": [] } + { "language": "java", "languageId": "java", "command": "/opt/jdtls/bin/jdtls", "args": [] }, + { "language": "python", "languageId": "python", "command": "pyright-langserver", "args": ["--stdio"] } ] } EOF -# ---- Directories & non-root user ---- -RUN mkdir -p /workspace /go && \ +# ---- 权限与目录 ---- +RUN mkdir -p /workspace /go /app/logs && \ groupadd --system app && \ useradd --system --gid app --home-dir /home/app --create-home app && \ - chown -R app:app /app /workspace /go /home/app + chown -R app:app /app /workspace /go /home/app /app/logs ENV PORT=8080 \ WORKSPACE_DIR=/workspace + +VOLUME ["/app/logs"] + EXPOSE 8080 USER app -ENTRYPOINT ["/app/server"] + +# 🔴 关键:用 entrypoint 脚本在启动时写 go.mod,避免被 volume 挂载覆盖 +# 如果 /workspace 下还没有 go.mod,自动创建一个最小的 +ENTRYPOINT ["sh", "-c", "test -f /workspace/go.mod || printf 'module workspace\n\ngo 1.25\n' > /workspace/go.mod; exec /app/server"] \ No newline at end of file diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index 5eef4f6..51b270c 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -735,6 +735,12 @@ func defaultLanguageServers() []completion.LanguageServerSpec { Command: "typescript-language-server", Args: []string{"--stdio"}, }, + { + Language: "python", + LanguageID: "python", + Command: "pyright-langserver", + Args: []string{"--stdio"}, + }, } } @@ -754,6 +760,7 @@ func applyLanguageServerEnvOverrides(servers []completion.LanguageServerSpec) [] overridden = applySingleLanguageServerEnv(overridden, "go", "go", "GO_LSP_COMMAND", "GO_LSP_ARGS", "gopls", "") overridden = applySingleLanguageServerEnv(overridden, "javascript", "javascript", "JAVASCRIPT_LSP_COMMAND", "JAVASCRIPT_LSP_ARGS", "typescript-language-server", "--stdio") overridden = applySingleLanguageServerEnv(overridden, "typescript", "typescript", "TYPESCRIPT_LSP_COMMAND", "TYPESCRIPT_LSP_ARGS", "typescript-language-server", "--stdio") + overridden = applySingleLanguageServerEnv(overridden, "python", "python", "PYTHON_LSP_COMMAND", "PYTHON_LSP_ARGS", "pyright-langserver", "--stdio") return overridden } diff --git a/backend/config.example.json b/backend/config.example.json index 338f830..edc2b99 100644 --- a/backend/config.example.json +++ b/backend/config.example.json @@ -56,6 +56,14 @@ "languageId": "java", "command": "/opt/jdtls/bin/jdtls", "args": [] + }, + { + "language": "python", + "languageId": "python", + "command": "pyright-langserver", + "args": [ + "--stdio" + ] } ] } diff --git a/backend/config.json b/backend/config.json index 1ff0c33..4c486bf 100644 --- a/backend/config.json +++ b/backend/config.json @@ -56,6 +56,14 @@ "languageId": "java", "command": "jdt-language-server-1.57.0-202602111032/jdtls.bat", "args": [] + }, + { + "language": "python", + "languageId": "python", + "command": "pyright-langserver", + "args": [ + "--stdio" + ] } ] }