面向单机 / 少量服务器 · 适合 Go / Rust / Deno 单二进制项目

一条命令,部署整个项目

OpenDeploy 是一个轻量级 Linux 服务自动部署 CLI。它通过 SSH 自动完成构建、打包上传、原子替换、systemd 托管、Nginx 同步和 HTTP 健康检查。无需 Docker,无需编写复杂 CI/CD 脚本,重复部署幂等一致。

MIT License Node >= 18 命令: opendeploy v0.9.0

OpenDeploy 是什么

OpenDeploy 是一个开源的轻量级 Linux 服务器部署 CLI(命令行工具)。它通过 SSH 将本地构建产物上传到目标服务器,并通过原子替换、systemd 服务管理和 HTTP 健康检查完成自动化部署。

它主要面向使用 Go、Rust 或 Deno 构建的单二进制项目,适合需要将服务直接部署到单台或少量 Linux VPS 的开发者。OpenDeploy 不依赖 Docker,不替代完整的容器编排平台,而是提供一条命令完成从构建到上线全流程的能力。

适用场景

了解 OpenDeploy 适合什么项目、不适合什么场景,有助于判断是否选用。

✓ 适合以下场景

  • 需要将 Go / Rust / Deno 服务直接部署到 Linux VPS
  • 不希望为小型项目引入 Docker 或复杂 CI/CD 流水线
  • 需要同时部署核心服务和后台管理服务
  • 希望重复部署时保持幂等(结果一致)
  • 需要原子替换,部署过程中服务不中断
  • 需要 HTTP 健康检查确认服务可用

— 不适合以下场景

  • 需要创建和管理云服务器实例
  • 需要配置 DNS 解析或申请 TLS 证书
  • 需要完整的容器编排平台(Kubernetes 等)
  • 需要蓝绿部署或灰度发布等高级发布策略
  • 项目无法编译为单一二进制文件

核心能力

OpenDeploy 将部署流程中的关键环节自动化,每个环节都可以独立引用和理解。

01

自动构建

逐个服务执行 build 命令,Go 项目自动注入 GOOS=linux GOARCH=amd64 CGO_ENABLED=0

02

SSH / tar 上传

将 deploy/ 目录 tar 打包,通过 scp 上传到远端 /tmp,无需额外传输工具

03

原子替换

使用同文件系统 rename 替换二进制文件,替换过程中服务不中断

04

systemd 托管

多服务逐个生成 unit 文件,hash 比对后按需更新并 daemon-reload + restart

05

Nginx 同步

项目自带 nginx.conf 时自动备份、替换、测试、reload,失败自动回滚

06

HTTP 健康检查

curl 127.0.0.1:{port}{health_path},3 秒超时,15 次重试确认服务可用

07

幂等执行

重复部署结果一致,配置未变化时不执行无意义的 reload 或 restart

08

多服务部署

支持同一项目多个二进制服务(核心 + 后台),共用部署目录,各自独立托管

部署流程

OpenDeploy 按以下 8 步顺序执行部署,幂等设计保证重复运行结果一致。

01
校验声明读取 deploy.yaml,多服务逐项校验 + 服务名重查 + deploy_dir 必填
02
本地构建逐个服务构建,逐个确认 deploy/{name}.new;失败即终止
03
打包上传tar 打包 deploy/ 目录,scp 上传到远端 /tmp
04
远端解包所有服务共享 deploy_dir,解压一次并执行 deploy.sh
05
原子替换每个服务同文件系统 rename,替换过程中服务不中断
06
systemd 托管多服务逐个生成 unit;hash 比对,变更才更新 + daemon-reload,然后 restart。deploy --force 时无条件覆盖 + daemon-reload + restart
07
健康检查每个服务 curl 127.0.0.1:{port}{health_path},3s 超时 · 15 次重试
08
Nginx 安全生效存在 nginx.conf 才执行:备份 → 替换 → nginx -t → reload,失败自动回滚

5 分钟快速开始

三步完成首次部署:安装、初始化、部署。

# 1. 全局安装
$ npm i -g open-deployer

# 2. 在项目根目录初始化(生成 deploy.yaml 和 nginx.conf 模板)
$ opendeploy init

# 3. 校验部署声明与前置环境
$ opendeploy check

# 4. 执行部署
$ opendeploy deploy

建议将 deploy/ 目录加入 .gitignore,避免将部署配置和构建产物提交到版本控制。

deploy.yaml 配置参考

项目根目录下 deploy/deploy.yaml 声明部署需求。以下是完整示例:

# deploy/deploy.yaml
ssh: wutuo               # ~/.ssh/config 主机别名(建议免密→部署全自动;密钥带口令/密码认证则部署时交互输入)
deploy_dir: /opt/uploadbroker   # 必填:所有服务共享的远端部署目录
services:              # 多服务标准结构;单服务项目写一项即可
  - name: uploadbroker    # 服务唯一标识,派生二进制名、systemd/nginx 配置名
    build: go build -ldflags "-s -w" -o deploy/uploadbroker.new ./cmd/server
    port: 8302              # 服务监听端口,仅用于本机 health check
    health_path: /v1/health  # 状态检查端点,固定 3s 超时
    # args: --config ./app.toml  # 可选:传给二进制的原始 argv
  - name: uploadbroker-admin    # 第二个服务(核心 + 后台)
    build: go build -ldflags "-s -w" -o deploy/uploadbroker-admin.new ./cmd/admin
    port: 8303
    health_path: /v1/health

配置字段说明

ssh
SSH 主机别名,读取 ~/.ssh/config建议配置免密登录以实现全自动部署
deploy_dir
远端部署目录所有服务共享,必填
services
服务列表支持单服务或多服务(核心 + 后台)
name
服务唯一标识派生二进制名、systemd unit 名和 nginx 配置名
build
构建命令Go 项目自动注入 GOOS/GOARCH/CGO_ENABLED
port
服务监听端口仅用于本机 health check
health_path
健康检查端点固定 3s 超时
args
传给二进制的原始 argv可选

对 Go 项目,OpenDeploy 会自动注入 GOOS=linux GOARCH=amd64 CGO_ENABLED=0,build 命令里无需手写。多个服务共用一个 deploy_dir,各自独立托管 systemd 与 health check。

命令参考

OpenDeploy 提供三个命令,覆盖从初始化到部署的完整流程。

opendeploy init生成 deploy.yaml 与 nginx.conf 模板
opendeploy check校验部署声明与前置环境,不实际部署
opendeploy deploy [-f|--force]执行完整的 8 步自动部署;--force 跳过 unit hash 比对,无条件覆盖 + daemon-reload + restart(适用于二进制未变但配置已变,如监听端口调整)

与其他方案的区别

OpenDeploy 定位在"手写 SSH 脚本"和"完整 CI/CD 平台"之间,适合单机/少量服务器场景。

方案 无需 Docker 原子替换 systemd 托管 健康检查 配置量
OpenDeploy ✓ ✓ ✓ ✓ 一个 yaml
手写 SSH 脚本 ✓ — 手动 手动 脚本维护
Docker 需要 ✓ 容器 手动 Dockerfile
GitHub Actions ✓ — 手动 手动 workflow yaml
Ansible ✓ — ✓ 手动 playbook

环境要求

OpenDeploy 对客户端和目标服务器有各自的要求。

命令用途平台说明
ssh / scp远程连接与上传Win 10 1803+ 自带;macOS / Linux 自带
tar打包上传(gz)Windows 自带 bsdtar
go执行 build 命令仅为示例,实际由 deploy.yaml 决定
curl / systemd / nginx健康检查 / 服务托管 / 反代需在部署目标服务器上就绪

DNS 解析、TLS 证书等根域名级、几乎不变的一次性配置,需自行手动维护,不在本框架范围内。

常见问题

以下是关于 OpenDeploy 的常见问题及独立、直接的回答。

OpenDeploy 是否需要 Docker?

不需要。OpenDeploy 通过 SSH 将构建产物直接部署到 Linux 服务器,并使用 systemd 托管服务,不依赖 Docker 或容器技术。服务器仍然需要准备 systemd、curl,以及在需要时使用 Nginx。

OpenDeploy 支持哪些操作系统?

客户端支持 macOS、Linux 和 Windows 10 1803+(自带 OpenSSH)。目标服务器需要是 Linux 系统,并具备 systemd、curl,以及在需要时使用 Nginx。

OpenDeploy 是否只支持 Go 项目?

OpenDeploy 适用于任何能编译为单一二进制文件的项目,包括 Go、Rust 和 Deno。对于 Go 项目,OpenDeploy 会自动注入 GOOS=linux GOARCH=amd64 CGO_ENABLED=0 环境变量,build 命令中无需手写。其他语言需要自行在 build 命令中处理交叉编译。

如何部署两个或多个服务?

在 deploy.yaml 的 services 列表中声明多个服务即可。每个服务有独立的 name、build、port 和 health_path,但所有服务共用同一个 deploy_dir 部署目录。OpenDeploy 会逐个构建、逐个托管 systemd 并逐个执行健康检查。

deploy_dir 为什么要求多个服务共用?

deploy_dir 是所有服务共享的远端部署目录。OpenDeploy 会将所有服务的构建产物打包上传到该目录,然后逐个执行原子替换。这样设计是为了简化部署流程——只需一次上传即可更新所有服务。

配置变化后是否一定会重启服务?

不一定。OpenDeploy 会对比 systemd unit 文件的 hash,只有在配置发生变化时才会更新 unit 文件并执行 daemon-reload + restart。如果配置没有变化,不会执行无意义的重启。使用 --force 参数可以跳过 hash 比对,无条件覆盖并重启。

OpenDeploy 是否负责 DNS 和 TLS 证书?

不负责。DNS 解析和 TLS 证书属于根域名级、几乎不变的一次性配置,需要自行手动维护,不在 OpenDeploy 的范围内。OpenDeploy 专注于应用部署本身。

如果健康检查失败会发生什么?

OpenDeploy 会对每个服务执行 curl 127.0.0.1:{port}{health_path} 健康检查,3 秒超时,最多重试 15 次。如果所有重试均失败,部署会终止并报告错误,但已替换的二进制文件不会自动回滚。

--force 参数什么时候应该使用?

当二进制文件未变化但配置已变化时(例如调整了监听端口),使用 --force 可以跳过 unit hash 比对,无条件覆盖 systemd 配置并执行 daemon-reload + restart。正常部署时无需使用。