ShipDesk 完整使用教程:从新建项目到 SSH 自动发布
一款本地优先的 Linux 发布工作台使用手册
本文适合:第一次使用 ShipDesk 的开发者、需要把项目交给客户配置的技术服务商,以及准备销售 ShipDesk 的产品负责人。

先说结论:ShipDesk 解决什么问题
如果你现在发布一个 Java 服务,需要反复做下面这些事情:
- 本地执行 Maven 构建。
- 找到正确的 JAR 文件。
- 登录服务器。
- 上传 JAR。
- 停掉旧进程。
- 替换线上文件。
- 启动新进程。
- 反复执行健康检查。
- 出问题后再手动回滚。
ShipDesk 把这套过程收进一个桌面工作台。你只需要填写项目配置,点击"开始发布",它会按固定流程执行:
text
本地构建
↓
获取远程发布锁
↓
同步项目专属启动/停止脚本
↓
上传不可变版本目录
↓
SHA-256 校验产物
↓
切换 current / previous 软链接
↓
停止旧版本
↓
启动新版本
↓
健康检查
↓
成功,或失败后自动回滚
当前版本的核心目标是"单台 Linux 服务器上的 Java JAR 发布"。界面里虽然预留了"静态文件 · Nginx"和"Custom Shell"选项,但这两个模板目前不会执行独立的发布流程,实际可用模板是 JAR · Linux · SSH。购买或交付给客户时,建议如实说明这一点。
一、使用前需要准备什么
1. 本地电脑
建议准备:
- macOS 或 Windows。
- Node.js 运行环境。
- 本机可以执行项目构建命令。
- 本机安装
ssh;如果使用密码登录,还需要sshpass。 - 如果使用 SSH 私钥,不需要
sshpass。
安装依赖并启动开发版本:
bash
npm install
npm start
构建桌面安装包:
bash
npm run build:mac
npm run build:win
2. 远程 Linux 服务器
服务器需要满足:
- 可以通过 SSH 访问。
- 用户有权创建和写入项目远程目录。
- 用户有权执行
chmod 755。 - 服务器安装了
sha256sum。 - 服务器安装了 Java,并且
java在 PATH 中。 - 如果配置健康检查,需要安装
curl或其他对应命令。 - 服务器使用标准 Linux shell 环境。
首次使用前可以在服务器上确认:
bash
java -version
sha256sum --version
curl --version
3. SSH 登录方式
ShipDesk 支持两种登录方式,二选一:
- 密码。
- SSH 私钥。
不能同时填写密码和私钥。生产环境更推荐 SSH 私钥,因为:
- 不需要在每次发布时输入密码。
- 更容易配合专用发布用户。
- 可以通过服务器端
authorized_keys管理权限。 - 不需要把密码写入命令行。
二、第一次打开 ShipDesk
打开应用后,左侧是项目列表,主区域是项目发布配置。顶部状态会显示当前连接和发布状态,右侧是发布进度。

第一次使用时,建议先创建一个独立的发布用户和独立项目目录,不要直接把多个服务全部放到 /data/project 根目录。
推荐目录规划:
text
/data/project/
├── knowledge-base-backend/
├── customer-portal/
└── order-service/
每个项目目录独立保存:
- 当前版本软链接。
- 上一个版本软链接。
- releases 版本目录。
- 项目启动脚本。
- 项目停止脚本。
- PID 文件和应用日志。
三、新建项目:每个字段到底怎么填
点击左侧"我的项目"旁边的 +,输入项目名称。
项目名称建议使用:
- 小写英文。
- 数字。
- 中划线。
- 与实际服务名称保持一致。
例如:
text
customer-portal
order-service
knowledge-base-backend
项目名称不是展示文字那么简单。ShipDesk 会用它和远程目录来生成项目专属脚本名称,例如:
text
customer-portal-start.sh
customer-portal-stop.sh

创建后,项目会出现在左侧列表中。新项目默认是空配置,需要按照下面四个区块填写。
四、第一部分:服务器与凭据
1. 服务器地址
填写服务器的 IP 或域名。
示例:
text
app.example.com
或者:
text
192.0.2.10
建议生产环境使用域名,因为服务器更换 IP 时不用修改所有项目配置。
2. 用户名
填写执行发布的 Linux 用户。
开发测试可以使用 root,但正式销售或交付时更推荐创建专用用户:
text
deploy
这个用户至少需要:
- 登录服务器。
- 写入项目远程目录。
- 执行项目启动和停止脚本。
- 执行
chmod 755。
3. SSH 端口
默认是:
text
22
如果服务器 SSH 使用其他端口,例如 2222,就填写:
text
2222
4. 密码
如果选择密码登录,在这里填写服务器密码。
密码不会写入发布命令日志,应用会尝试通过系统安全存储保存凭据。销售给客户时,不要把你的服务器密码预填进安装包。
5. 私钥路径
如果选择私钥登录,填写本机私钥路径,例如:
text
~/.ssh/id_ed25519
或填写绝对路径:
text
/Users/your-name/.ssh/id_ed25519
Windows 示例:
text
C:\\Users\\your-name\\.ssh\\id_ed25519
密码和私钥只能选一个。为了避免发布时遇到权限问题,可以先在终端验证:
bash
ssh -i ~/.ssh/id_ed25519 deploy@app.example.com
五、第二部分:构建与产物
1. 本地工作目录
这是构建命令执行的目录,产物路径也相对于它计算。
例如项目位于:
text
/Users/your-name/work/knowledge-base-backend
那么填写:
text
/Users/your-name/work/knowledge-base-backend
Windows 示例:
text
C:\\Users\\your-name\\work\\knowledge-base-backend
注意:这个路径是本机路径,不是服务器路径。
2. 本地构建命令
填写你平时在项目目录中执行的构建命令。
Maven 多模块项目示例:
bash
mvn -pl kb-server -am package -DskipTests
普通 Maven 项目示例:
bash
mvn clean package -DskipTests
Gradle 项目示例:
bash
./gradlew clean bootJar -x test
如果项目不需要构建,也可以留空,直接上传现有产物。但在销售教程中建议提醒客户:留空意味着 ShipDesk 不会替客户检查源码是否已经构建。
3. 产物路径
填写构建产物相对于"本地工作目录"的路径。
Maven JAR 示例:
text
kb-server/target/kb-server-1.0.0-SNAPSHOT.jar
使用通配符匹配版本号:
text
kb-server/target/*.jar
Gradle 示例:
text
build/libs/customer-portal-*.jar
这个路径不是服务器上的路径。ShipDesk 会先在本机找到文件,再把文件上传到远程版本目录。
构建配置检查方法
在点击"开始发布"前,先进入项目目录手动执行一次:
bash
cd /Users/your-name/work/knowledge-base-backend
mvn -pl kb-server -am package -DskipTests
ls -lh kb-server/target/*.jar
如果最后一条命令找不到文件,ShipDesk 也无法上传。
六、第三部分:远程发布
这是最重要的配置区块。
1. 远程数据目录
填写当前项目在服务器上的固定根目录。
例如:
text
/data/project/knowledge-base-backend
这个目录用于保存项目运行相关文件,包括自动生成的脚本、PID 文件、日志和版本软链接。
不同项目不要共用同一个远程数据目录:
text
正确:/data/project/knowledge-base-backend
正确:/data/project/customer-portal
错误:/data/project
2. 远程上传目录
当前 JAR 发布模板建议填写与"远程数据目录"相同的路径:
text
/data/project/knowledge-base-backend
ShipDesk 会在这个目录下创建:
text
releases/<releaseId>
current -> releases/<releaseId>
previous -> releases/<oldReleaseId>
不建议把远程上传目录填写到某个具体 JAR 文件路径,也不要写成每次手动变化的版本目录。
3. 停止命令
新建项目可以先留空。
当停止命令留空时,ShipDesk 会自动生成并同步项目专属的停止脚本,例如:
text
/data/project/knowledge-base-backend/knowledge-base-backend-stop.sh
如果你已经有经过验证的自定义停止脚本,也可以填写完整命令:
bash
/data/project/knowledge-base-backend/custom-stop.sh
4. 启动命令
新建项目可以先留空,ShipDesk 会自动生成并同步项目专属启动脚本,例如:
bash
/data/project/knowledge-base-backend/knowledge-base-backend-start.sh restart
如果填写自定义命令,可以使用模板变量:
bash
JAVA_OPTS="{{javaOpts}}" /data/project/knowledge-base-backend/custom-start.sh restart
支持的常用变量包括:
| 变量 | 含义 |
|---|---|
{``{releaseId}} |
本次发布的版本 ID |
{``{releaseDir}} |
本次版本目录 |
{``{remoteRoot}} |
远程发布根目录 |
{``{currentLink}} |
current 软链接路径 |
{``{previousLink}} |
previous 软链接路径 |
{``{artifact}} |
上传产物文件名 |
{``{appPort}} |
项目端口 |
{``{javaOpts}} |
JVM 参数 |
5. JVM 参数
Java 服务示例:
text
-Xms1g -Xmx1g -XX:+UseG1GC -XX:MaxGCPauseMillis=200
如果服务器内存较小,可以填写:
text
-Xms256m -Xmx512m
不要盲目复制大内存参数。JVM 最大堆内存过大,可能导致服务器本身或其他服务内存不足。
自动脚本同步机制
新项目使用自动脚本时,发布前会执行以下逻辑:
text
生成本项目的 start.sh / stop.sh
↓
计算本地脚本 SHA-256
↓
检查远程目录中是否存在同名脚本
↓
比较远程脚本 SHA-256
├── 一致:跳过上传
└── 缺失或不一致:上传并 chmod 755
↓
再次校验远程脚本
这样做有两个好处:
- 每个项目都有自己的启动和停止脚本,不会误调用其他项目的脚本。
- 脚本没有变化时不会重复上传。
七、第四部分:启动验证
健康检查命令
Spring Boot 项目常用:
bash
curl -fsS http://127.0.0.1:8091/actuator/health
如果服务暴露的是 /health:
bash
curl -fsS http://127.0.0.1:8080/health
如果使用 HTTP 状态码检查:
bash
curl -f http://127.0.0.1:8080/
curl -f 的作用是让非 2xx/3xx 响应返回失败,ShipDesk 才能判断本次启动没有通过检查。
如果没有健康检查命令,发布流程无法可靠判断"进程启动了但服务不可用"的情况。生产环境建议一定配置。
八、保存、校验与发布的正确顺序
推荐每次按下面顺序操作:
- 填写或修改配置。
- 点击"保存配置"。
- 确认右侧状态变成"已保存"。
- 点击"校验配置"。
- 确认出现"配置校验通过"。
- 点击"开始发布"。
如果看到"当前配置有未保存修改",说明你刚才修改了字段但没有成功保存。不要直接切换项目或关闭应用,先点击"保存配置"。

九、发布过程中会看到什么
右侧发布进度会依次展示:
- 构建。
- 上传不可变版本。
- 切换
current/previous。 - 停止旧版本。
- 启动。
- 验证。
- 失败自动回滚。
点击发布后,按钮会立即变成"发布中...",并出现"已收到发布请求"的提示,不需要猜测按钮是否生效。
日志中可能看到:
text
[锁定] 获取远程发布锁
[脚本] knowledge-base-backend-start.sh 已存在且内容一致,跳过上传
[脚本] knowledge-base-backend-stop.sh 已存在且内容一致,跳过上传
[上传] 创建不可变版本目录 /data/project/knowledge-base-backend/releases/release-...
[校验] 对比远程产物哈希
[激活] current -> release-...
[验证] 最多等待 60 秒
发布 release-... 成功
实时日志页面可以查看完整日志。

十、服务器上的最终目录结构
假设项目配置为:
text
远程数据目录:/data/project/knowledge-base-backend
远程上传目录:/data/project/knowledge-base-backend
产物:kb-server-1.0.0-SNAPSHOT.jar
成功发布几次后,服务器大致如下:
text
/data/project/knowledge-base-backend/
├── knowledge-base-backend-start.sh
├── knowledge-base-backend-stop.sh
├── .shipdesk.pid
├── app.log
├── current -> releases/release-20260920...
├── previous -> releases/release-20260919...
└── releases/
├── release-20260919.../
│ └── kb-server-1.0.0-SNAPSHOT.jar
└── release-20260920.../
└── kb-server-1.0.0-SNAPSHOT.jar
current 和 previous 是软链接,不是复制出来的两份大文件。切换版本时,ShipDesk 使用临时软链接和原子移动,降低切换过程中出现半成品目录的概率。
十一、如何测试连接
进入左侧"服务器"页面,确认服务器地址、用户名、SSH 端口和远程数据目录,然后点击"测试连接"。

测试连接成功,只能说明 SSH 可以访问服务器,不代表:
- 本地构建一定成功。
- 产物路径一定正确。
- 远程目录一定有写权限。
- Java 一定安装正确。
- 健康检查一定能通过。
所以测试连接后仍然要完整校验项目配置。
十二、常见问题排查
问题 1:点击发布没有任何反应
检查:
- 是否填写了服务器地址。
- 是否填写了用户名。
- 是否填写密码或私钥。
- 是否填写本地工作目录。
- 是否填写产物路径。
- 是否填写远程上传目录。
现在点击通过校验后,按钮会立即进入"发布中..."状态。如果完全没有变化,建议重启应用并确认使用的是最新构建包。
问题 2:找不到构建产物
先在本地执行:
bash
cd /你的工作目录
ls -lh 产物路径
产物路径必须相对于工作目录填写,不能把本机绝对路径和服务器路径混在一起。
问题 3:sshpass 退出码 1
常见原因:
- 密码错误。
- SSH 端口错误。
- 服务器拒绝 root 登录。
- 本机没有安装
sshpass。 - 远程目录没有写权限。
更推荐改用 SSH 私钥,并手动验证:
bash
ssh -i ~/.ssh/id_ed25519 -p 22 deploy@app.example.com
问题 4:.shipdesk.lock: File exists
这是上一次发布被强制中断后遗留的发布锁。
当前版本会自动清理超过默认过期时间的锁。如果确认没有其他发布正在执行,也可以安全地删除空锁目录:
bash
ssh deploy@app.example.com "rmdir /data/project/knowledge-base-backend/.shipdesk.lock"
使用 rmdir 而不是 rm -rf,可以避免误删非空目录。
问题 5:脚本上传后仍然启动失败
检查:
bash
ls -l /data/project/knowledge-base-backend/*-start.sh
ls -l /data/project/knowledge-base-backend/*-stop.sh
cat /data/project/knowledge-base-backend/app.log
确认:
- 脚本权限是
-rwxr-xr-x或至少包含执行权限。 - 服务器存在 Java。
current软链接存在。current目录下有产物。- 产物文件名和脚本中的文件名一致。
问题 6:健康检查失败,但服务进程似乎在运行
进程存在不代表接口已经可用。可以先手动执行:
bash
curl -v http://127.0.0.1:8091/actuator/health
如果应用启动较慢,可以增加健康检查等待时间和间隔配置,或者先检查应用日志。
十三、发布历史与审计
"审批与历史"页面会展示本机记录的:
- 项目。
- 环境。
- 发布状态。
- 完成时间。

这份历史记录适合个人和小团队使用。当前版本是本机优先设计,历史记录保存在本机,不是云端团队审计系统。
十四、当前模板能力说明

JAR · Linux · SSH
当前可用,适合:
- Spring Boot。
- Java Web 服务。
- Maven 或 Gradle 构建的 JAR 应用。
- 使用 Linux 服务器运行 Java 进程的项目。
静态文件 · Nginx
当前界面已预留选项,但发布引擎还没有接入独立的静态文件递归上传和 Nginx 切换流程。选择后会明确提示模板暂不可用,不会悄悄按 JAR 流程发布。
Custom Shell
当前界面已预留选项,但还没有接入独立的自定义 Shell 发布策略。销售时不要把它描述成已经支持的功能。
十五、给客户交付时的配置清单
可以把下面这份清单直接发给客户:
客户需要提供
- 项目名称。
- 服务器 IP 或域名。
- SSH 用户名。
- SSH 端口。
- 密码或 SSH 私钥。
- 本地项目目录。
- 构建命令。
- 构建产物路径。
- 远程项目目录。
- 健康检查 URL。
- JVM 参数。
客户需要确认
- 远程目录属于当前项目,没有和其他服务共用。
- SSH 用户可以写入远程目录。
- SSH 用户可以执行脚本。
- Java 版本符合项目要求。
- 健康检查命令在服务器上可以手动执行。
- 已经完成一次测试环境发布。
- 已经确认失败回滚逻辑。
十六、发布前最终检查
产品检查
- 安装包可以启动。
- 新建项目可以保存。
- 保存后不会持续提示未保存修改。
- 发布按钮点击后会立即显示处理中。
- 错误信息可见。
- 当前模板能力说明准确。
客户配置检查
- 服务器地址没有写错。
- SSH 端口没有写错。
- 密码和私钥只选一个。
- 工作目录是本机目录。
- 产物路径相对于工作目录。
- 远程目录是当前项目专属目录。
- 健康检查可以手动执行。
- 不同项目没有复用同一个远程目录。
安全检查
- 教程截图已经脱敏。
- 不把真实服务器密码写进文档。
- 不把真实私钥提交到项目。
- 客户使用专用发布账号。
- 生产环境发布前先做测试环境验证。
- 服务器端脚本权限最小化。
总结
ShipDesk 的正确使用方式不是把所有服务器命令都塞进输入框,而是为每个项目建立清晰的边界:
- 一个项目对应一个远程目录。
- 一个远程目录对应一组项目脚本。
- 一个发布对应一个不可变版本目录。
current指向当前版本。previous保留上一个可回滚版本。
对于当前版本,推荐从 JAR · Linux · SSH 模板开始。新建项目时把服务器、构建、产物、远程目录和健康检查配置清楚,启动/停止命令可以先留空,让 ShipDesk 自动生成和同步项目专属脚本。
这套方式最适合希望降低手工发布成本、又不想马上维护一整套云端 CI/CD 平台的个人开发者和小团队。