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
This commit is contained in:
2026-02-16 00:44:57 +08:00
parent 00b0d825d8
commit 5d5a094196
4 changed files with 66 additions and 24 deletions

View File

@@ -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"]

View File

@@ -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
}

View File

@@ -56,6 +56,14 @@
"languageId": "java",
"command": "/opt/jdtls/bin/jdtls",
"args": []
},
{
"language": "python",
"languageId": "python",
"command": "pyright-langserver",
"args": [
"--stdio"
]
}
]
}

View File

@@ -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"
]
}
]
}