1. 这个问题的场景,以及为什么值得写
一个挺让人抓狂的bug:在内网离线环境里配好了VS Code的SSH远程开发,连服务器一切正常,结果部署脚本一跑,生成的文件名永远带着 -staging 后缀。不是一次两次,是每次。model-abc123-staging.safetensors、model-def456-staging.safetensors……明明检查过Git提交记录是干净的,为什么工具就是觉得当前处于staging状态?
这个问题的根源不在VS Code,也不在SSH本身,而是我把一个叫 stable-commit-id 的Git辅助工具接进了部署流程。它本意是给部署产物打上稳定可溯源的提交标识,结果反而把整个文件名都搞乱了。
先说清楚背景。我这边负责的是一套跑在客户内网的AI推理服务,类似AnythingLLM、Dify或者Stable Diffusion WebUI这类,数据不能出内网,算力也在服务器上,所以日常开发全部走VS Code Remote-SSH。本地Windows只是编辑器,代码、模型、训练脚本全在Linux服务器上。为了给模型和推理包做版本追溯,我在部署脚本里接了 stable-commit-id(标题里那个 "Stable-cmmit-id" 应该就是这玩意,多半是手滑漏了个字母)。这个工具会在每次构建时把当前Git提交的短哈希读出来,拼到产物文件名里。理论上应该是 model-abc123.safetensors,但离线环境下它一直给你输出 model-abc123-staging.safetensors,路径引用全乱套。
这篇文章就把完整排查过程和最终方案写出来,给同样在离线环境里折腾VS Code Remote-SSH、又踩了Git钩子/commit-id工具坑的人一个参考。前半段聊环境配置,后半段聊那个万恶的staging后缀到底从哪来。
1.1 内网离线开发的一个典型困境
先别急着改脚本,得先理解离线环境下的Remote-SSH是个什么结构。VS Code的Remote-SSH原理其实很简单:你在本地装一个 Remote-SSH 扩展,连接远程服务器后,VS Code会把整个编辑器核心(vscode-server)部署到服务器上,本地只负责渲染界面和接收键盘鼠标事件。你的代码、终端、调试、插件,全部跑在远程。
这个设计在公网环境很省事,但到了离线环境就麻烦了。我第一次在客户内网服务器上配Remote-SSH,连接时报错,打开Remote-SSH日志一看,它在尝试从微软的更新服务器下载vscode-server的压缩包,当然下载失败。这时候需要手动把vscode-server传上去。另一个麻烦是扩展:本地能用插件市场,远程服务器默认也能用,但离线环境下插件市场根本访问不了,远程扩展装不上,等于连了个“残废”编辑器。
这还只是环境问题。真正让我头疼的是后面:环境配好之后,部署脚本里的 stable-commit-id 又开始捣乱,给文件名加staging后缀。这两个问题在实战中经常一起出现,所以我把环境配置和这个Git工具的问题都整理成一篇,方便你一条龙排查。
1.2 Stable Commit ID 到底在扮演什么角色
stable-commit-id 这个工具,说穿了就是“把Git提交哈希变成部署产物文件名的一部分”。举个例子:你今天提交了一个改动,提交哈希是 abc123,部署脚本会把模型文件重命名成 model-abc123.safetensors。下次再提交,哈希变成 def456,产物就是 model-def456.safetensors。这样无论集群里部署了多少个版本,通过文件名就能一眼看出是哪个commit构建出来的。
为什么不用时间戳?因为时间戳太容易撞了,而且无法精确对应到代码状态。Git提交哈希是内容寻址的,同样的代码必然生成同样的哈希,这个特性对于复现和回滚非常关键。所以很多部署流水线都有类似工具,Vite有版本号插件,Docker镜像有IMAGE_TAG,我们这里的模型文件就直接拿commit id当tag。
这个工具常见的实现方式是挂在Git钩子里,或者放在构建脚本里作为一个函数调用。它读当前HEAD的哈希,再做一些环境判断,最后输出一个字符串。问题就出在“环境判断”这一步——它判断出当前处于staging状态,就给文件名追加了 -staging。要搞清楚它为什么这么判断,得先明白Git的staging到底是什么意思。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先把 VS Code 的 SSH 离线部署环境配好
在排查Git问题之前,我强烈建议先把离线开发环境彻底理顺。因为很多怪问题其实是环境没配好导致的,比如vscode-server版本不对、插件装不上,你会误以为是自己代码或者脚本的问题。以下是我实测过很多次的离线配置流程。
2.1 服务器端准备
服务器这边的前提是sshd必须活着,并且允许密钥登录。大部分Linux发行版默认装了OpenSSH Server,但有些精简镜像没装,需要先装一下。离线环境装包是另一个话题,这里先假设sshd已经是可用状态。
