upy单二进制 Web 部署工具

一个二进制,从 Release 直达生产。

Go 单二进制,零外部依赖,极低内存占用。
快速将 GitHub Releases 或本地 bundle 部署至服务器,原生支持 SPA 与 Docker 项目。

Linux / macOS · x86_64 / arm64 · 零外部依赖

构建产物 → upy 调度 → 生产环境
蓝色 Go Gopher 踩着滑板,放置在工程辅助线之间
Release Bundleupy生产环境
极速部署 磁盘清理 约定备份 项目分析 Bark / Webhook

安装

单行命令安装。

自动识别系统架构并配置 Shell Tab 命令补全。
单二进制零依赖,无后台常驻进程。

查看安装文档 ↗
安装脚本
curl -fsSL https://raw.githubusercontent.com/AaronConlon/upy/main/install.sh | bash

默认安装至 /usr/local/bin,支持通过 INSTALL_DIR 指定安装路径。

核心功能

部署、清理、备份与告警。

覆盖应用发布、磁盘空间维护、关键数据备份与多人移动端告警,构建单机运维闭环。

01 / 部署

从 Release 到生产,原子秒级切换。

在终端交互选择 GitHub Releases 资产包,或一行命令直接部署最新版本。 支持断点续传与 SHA-256 完整性校验;离线环境下支持本地 bundle 文件。

查看部署指南 ↗
部署命令
# 交互选择 Release 资产
upy release

# 部署最新正式版
upy release latest

# 部署本地 bundle 文件
upy bundle ./bundle.zip
SPA 静态站点

原子软链切换,自适应权限规整。

解压至独立版本目录,通过 current 软链原子切换。 自动将目录与文件规整为 0755/0644 权限,避免 Nginx / Caddy 出现 403 权限错误。

原生 Systemd 服务

Go 二进制原子纳管,拒绝静默提权。

纳管 Go/Rust 等轻量常驻进程。 严格预检运行账号与权限,启动参数原样保真,端口身份严密防伪,失败秒级自动回滚。

Docker / Compose 容器项目

平滑启停,失败自动回滚。

新版本镜像与配置就绪后再停止旧容器并释放端口,避免端口冲突。 内置健康检查机制,启动异常时自动回滚至上一可用版本。

三大部署实战全流程:从 CI 打包到服务器运行

真实还原三大模式的完整流水线 —— 包含 CI 自动化打包脚本、服务器目录结构、真实终端执行日志与底层可靠性保障。

01 CI/CD 自动化打包
.github/workflows/deploy.yml
# 1. 构建前端产物
- name: Build frontend
  run: npm ci && npm run build

# 2. 写入清单并打成 bundle.zip
- name: Package bundle
  run: |
    cat << 'EOF' > dist/upy.yaml
    name: my-spa-app
    version: ${{ github.ref_name }}
    type: static
    static:
      directory: dist
    EOF
    cd dist && zip -r ../bundle.zip . upy.yaml
02 服务器端配置与目录布局
/var/www/my-spa-app/deploy.yaml
# 服务器端项目配置
name: my-spa-app
release:
  provider: github
  repository: owner/my-spa-app
  asset: bundle.zip

# 压缩包与版本保留策略 (默认最多保留 3 个 bundle 压缩包,范围 0~100)
bundles:
  keep: 3
releases:
  keep: 1

# Nginx 配置指向软链: root /var/www/my-spa-app/current;
host: /var/www/my-spa-app
$ upy release latest
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  📦 项目: my-spa-app
  📁 目录: /var/www/my-spa-app
  🧩 类型: 静态站点 (static)
  🏷 当前版本: 未部署
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  -> 正在获取 owner/my-spa-app 的 v1.0.0 版本...
  ✓ 已选择版本 v1.0.0
  -> ⬇️  正在下载资产 bundle.zip(1.4MB)...
  ✓ 已保存到 bundles/v1.0.0-bundle.zip
  -> 正在解压 bundle...
  ✓ bundle 解压完成
  -> 正在校验静态 bundle 入口...
  ✓ 静态 bundle 校验通过 (dist/index.html 存在)
  -> 正在自适应修复目录与文件权限...
  ✓ 目录权限修正为 0755,文件权限修正为 0644
  -> 正在原子切换 current 软链...
  ✓ current -> releases/1.0.0/dist
  ✓ 部署完成: my-spa-app 1.0.0
  ⏱ 部署耗时: 0.8s
彻底杜绝 403 Forbidden:递归自动规整目录权限为 0755,静态文件权限为 0644。
微秒级原子软链切换:通过 POSIX 原子重命名切换 current -> releases/1.0.0/dist,发布过程零中断。
双版本保护与秒级回滚:安全保留当前与上一版本,健康探测异常时软链瞬间切回上一成功版本。
02 / 清理

磁盘空间分析与安全清理。

部署时依据 bundles.keep 自动保留最新压缩包(默认最多 3 个,支持 0~100 自由定制); 支持通过 upy clean 交互式清理或一键常规瘦身。 内置双重活跃版本保护,禁止删除 current 正在运行的版本;通过跨进程互斥锁避免并发冲突。

查看清理文档 ↗
清理命令
# 交互式清理菜单(支持空间分析)
upy clean

# 仅清理历史 bundle 压缩包缓存
upy clean --bundles

# 一键常规瘦身(清理缓存与旧版本)
upy clean --all -y
03 / 备份

约定式数据备份,全流程加锁防护。

遵循约定优先原则,自动识别项目中的 backup.sh 脚本并注入环境变量。 执行期间自动施加跨进程排他互斥锁,严防并发写入产生脏数据;支持智能保留轮转策略与 Bark 移动端实时告警。

查阅备份与归档文档 ↗
01 / 约定备份脚本 零配置探测 backup.sh
#!/usr/bin/env bash
# 环境变量由 upy 自动注入: UPY_BACKUP_DIR, UPY_PROJECT_NAME, UPY_TIMESTAMP
mkdir -p "${UPY_BACKUP_DIR}"
BACKUP_FILE="${UPY_BACKUP_DIR}/dump-${UPY_PROJECT_NAME}-${UPY_TIMESTAMP}.sql.gz"

# 在容器内安全执行 mysqldump 导出并压缩
docker compose exec -T db mysqldump -u root -p"${DB_PASSWORD}" "${DB_NAME}" | gzip > "${BACKUP_FILE}"
02 / 上下文与轮转 可选进阶配置 deploy.yaml
# 备份功能配置(可选)
backup:
  script: backup.sh            # 自定义脚本路径(缺省自动探测)
  dir: backups                 # 备份产物归档目录(默认 backups/)
  retention: 7                 # 自动轮转保留的最大备份份数(默认 7)
  timeout: 15m                 # 备份最大超时时间(默认 15m,支持 30s, 5m, 1h)
终端执行 — upy backup
upy backup
$ upy backup
-> 正在对项目 my-api-service 执行约定备份...
✓ 发现约定脚本: backup.sh (chmod 0755)
✓ 已获取项目排他锁 (.deploy.lock)
-> 正在驱动执行备份脚本 (UPY_BACKUP_DIR=backups)...
------------------------------------------------------------
正在导出数据库到: /opt/my-api-service/backups/dump-my-api-service-20261019-120000.sql.gz...
数据库导出成功!
------------------------------------------------------------
✓ 项目 my-api-service 备份执行完成!
  📦 归档产物: dump-my-api-service-20261019-120000.sql.gz (42.5 MB)
  🛡️  自动轮转: 保留最近 7 份(已清理 1 份历史旧备份)
  ⏱  总耗时:   2.4s
  🔔 已向 Bark 渠道推送备份完成通知
upy backup 交互式选择已登记项目执行备份
upy backup my-app --list 查看项目历史备份列表与占用体积
upy backup my-app --prune 5 手动触发轮转,保留最近 5 份备份
upy backup --all -y 一键批量备份所有已登记项目
跨进程排他互斥(.deploy.lock):备份期间获取排他锁(action: 备份中),严格互斥正在进行的部署或磁盘清理,杜绝产生半更新脏数据。
智能自动轮转防爆盘:按修改时间排序自动剔除超出保留阈值的旧备份(默认 7 份),防止历史备份文件无限膨胀撑爆服务器磁盘。
通知告警实时推送:备份完成后自动汇总耗时、产物文件体积,并通过 Bark 等渠道实时推送备份结果与告警。
04 / 分析

客户端项目全景分析,以最大空间为 100% 基准。

全机纳管项目动态盘点,以占用空间最大的项目为 100% 基准绘制等宽横向柱状条形图; 顶栏置顶聚焦最近一次部署动态(项目、版本、部署类型、相对时间与健康状态)。严格杜绝软链双重计数,支持 --detail 深度展开与 --json 格式化导出。

查阅分析命令文档 ↗
01 / 100% 相对基准条形图 直观凸显大户 Max Benchmark Bar
# 算法:以占用最高的项目 maxBytes 为 100% 基准换算比例
1  my-compose-app  docker  1.45 GB  [████████████████████] 100.0%
2  my-api-service  system  482 MB   [███████░░░░░░░░░░░░░]  32.5%
3  portal-frontend static   86 MB   [█░░░░░░░░░░░░░░░░░░░]   5.8%
02 / 最近部署置顶卡片 实时动态追踪 Spotlight Focus
# 甄选 state.json 中时间戳最新的项目置顶高亮
📦 项目: my-api-service (v1.2.0)
🧩 类型: Systemd 系统服务 (system) · upy-my-api-service.service
⏱  时间: 22分钟前 (2026-10-19 19:40:02)
🟢 状态: 正常运行 (active)
终端执行 — upy analysis
$ upy analysis
upy analysis — 客户端项目与磁盘分析

━ 最近一次部署动态 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  📦 项目: my-api-service (v1.2.0)
  🧩 类型: Systemd 系统服务 (system) · upy-my-api-service.service
  ⏱  时间: 22分钟前 (2026-10-19 19:40:02)
  🟢 状态: 正常运行 (active)

━ 项目分析 (状态 · 空间基准对比 · 类型 · 版本号) ━━━━━━━━━━━
#   项目名称            状态           类型     当前版本    磁盘占用    基准对比 (Max)
1   my-compose-app      🟢 active      docker   v2.1.0      1.45 GB     [████████████████████] 100.0%
2   my-api-service      🟢 active      system   v1.2.0      482.3 MB    [███████░░░░░░░░░░░░░]  32.5%
3   portal-frontend     🟢 active      static   v0.9.4       86.1 MB    [█░░░░░░░░░░░░░░░░░░░]   5.8%
4   demo-spa            ⚪ undeployed  static   -            14.2 MB    [▏░░░░░░░░░░░░░░░░░░░]   0.9%

━ 存储汇总统计 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  📊 纳管项目: 4 个
  💾 累计占用: 2.03 GB (平均每个项目 519.6 MB)
  👑 空间首位: my-compose-app (1.45 GB, 占全机 upy 空间的 71.4%)
  💡 提示: 可使用 upy analysis --detail 查看各子目录详细空间分布
upy analysis 全机项目磁盘占用基准图与最近部署
upy analysis --detail 展开 releases/bundles/backups 子目录细分
upy analysis <name> 针对指定项目深入查看占用与目录树
upy analysis --json 以 JSON 结构化数据输出供监控解析
杜绝软链穿透双计:测算空间时严格仅计入 current 符号链接本身字节,不递归穿透目标版本目录,杜绝活跃版本重复计算。
子目录明细展开(--detail):清晰列出 releases(活跃与旧版)、bundles 缓存、backups 归档及 shared 目录的独立占用。
结构化导出(--json):直接输出标准 JSON,方便接入主机监控大屏、定时巡检警报或自动化审计脚本。
05 / 通知

多接收人 Bark 移动端推送与项目专属 Webhook。

部署与备份结果即时推送至 iOS 设备与团队业务系统。底层基于开源 Bark 移动端推送与项目级专属 Webhook。 无需第三方复杂配置,支持在 deploy.yaml 中项目级独立配置、全局配置兜底、团队多人广播、HMAC-SHA256 签名防伪与智能自动去重。

查阅通知配置文档 ↗
开源利器 什么是 Bark?
bark.day.app ↗

Bark 是一款针对苹果 iOS / iPadOS 设备的轻量、开源即时通知推送服务。只需要发送简单的 HTTP 请求,即可秒级将自定义通知推送至设备。upy 原生内建 Bark,提供零运维、即时响应的发布与备份观测能力。

01 / 统一配置结构 通用属性与多用户定义 deploy.yaml / ~/.upy/config.yaml
# 统一写法:通用属性(对所有成员生效) + 用户级列表(按 - name 区分多用户)
notify:
  bark:
    # 1. 通用属性 (全局/项目默认继承)
    serverUrl: https://api.day.app     # 通用服务端节点 (可填自建私有域名)
    group: "payment-api"               # 通用推送分组
    sound: "chime"                     # 通用提示音 (如 bell, chime, glass 等)
    level: "active"                    # 通用时效级别 (active / timeSensitive)

    # 2. 用户级属性 (按 - name 区分多用户,字段优先级高于通用字段)
    users:
      - name: "前端负责人"
        token: "DEVICE_KEY_ALICE"
        sound: "glass"                 # 用户级覆盖通用 sound
      - name: "值班运维"
        token: "DEVICE_KEY_BOB"
        serverUrl: https://bark.ops.internal # 覆盖通用 serverUrl
        level: "timeSensitive"
      - name: "测试工程师"
        token: "DEVICE_KEY_CAROL"      # 未指定独立属性,完全继承通用配置
02 / 单人直配模式 极简开箱即用 deploy.yaml
# 单人极简直配:直接在 bark 下声明 token 即可,完全继承通用设置
notify:
  bark:
    serverUrl: https://api.day.app
    group: "my-service"
    sound: "bell"
    token: "DEVICE_KEY_SINGLE_USER"
03 / 项目专属 Webhook 每个项目独立配置 · 无需全局配置 deploy.yaml
# 项目级独立 Webhook(不污染全局,支持单 URL、多端点与 HMAC 签名)
notify:
  webhook:
    - url: "https://ops.example.com/api/deploy-webhook"
      secret: "SEC_KEY_FOR_HMAC_SHA256"  # 附带 X-Upy-Signature 防伪签名
      headers:
        X-Environment: "production"
    - url: "https://qyapi.weixin.qq.com/.../send" # 企微/飞书/钉钉群机器人
04 / 推送内容规范 全方位上下文自动组装 Title & Body 结构
# Title 与 Body 无需手动拼写,upy 自动从运行时状态组装:
Title: upy 部署成功 · my-api-service
Body:
  项目: my-api-service
  版本: v1.2.0
  类型: Systemd 系统服务
  目录: /opt/my-api-service
  耗时: 3.2s
  # 若部署或备份异常,Body 自动附带「原因: <详细报错>」
终端执行 — 移动端推送
upy release latest
$ upy release latest
-> 正在发布项目 my-api-service v1.2.0...
✓ 系统服务配置校验通过
✓ 已更新 systemd unit 并指向 releases/1.2.0
✓ 系统服务已启动 (upy-my-api-service.service)
✓ 健康检查通过 (HTTP 200 OK)
✓ current -> releases/1.2.0
⏱ 总耗时: 3.2s
🔔 已向 3 个 Bark 接收人与 1 个项目 Webhook 推送通知:
  ✓ Alice (https://api.day.app) [HTTP 200]
  ✓ Bob (https://api.day.app) [HTTP 200]
  ✓ 运维负责人 (https://bark.mycorp.internal) [HTTP 200]
  ✓ Webhook: https://ops.example.com/api/deploy-webhook [HTTP 200]
🔔 Bark · 刚刚
部署成功
Title: upy 部署成功 · my-api-service
项目: my-api-service
版本: v1.2.0
类型: Systemd 系统服务
目录: /opt/my-api-service
耗时: 3.2s
💾 Bark · 2分钟前
备份归档
Title: upy 备份成功 · my-api-service
项目: my-api-service
归档: dump-my-api-service-20261019-120000.sql.gz (42.5 MB)
目录: /opt/my-api-service
耗时: 2.4s
项目专属 Webhook 隔离:Webhook 仅在项目的 deploy.yaml 中生效,独立配置不污染全局;支持 HMAC-SHA256 防伪签名 (X-Upy-Signature) 与投递跟踪标识。
用户级字段优先覆盖:按 - name 分多个用户,用户专属配置(如独立 sound 或私有 serverUrl)优先级高于外层通用字段,未指定字段自动回退继承通用配置。
项目与全局双层配置:项目专属配置(deploy.yaml)与机器全局兜底(~/.upy/config.yaml)协同运作,智能合并通知渠道。
智能跨量级耗时换算:严格遵守层级单位换算——小于 60s 展示秒数(3.2s),超过 60s 换算为分钟(1m15s),超过 60m 自动以小时开头(1h2m),告别机械全秒输出。
智能去重与独立静音:重叠 Token 自动去重仅推送一次;声明 notify: { enabled: false } 可随时独立静音该项目。
压缩包保留与 Shell 补全同步:支持在 deploy.yaml 中通过 bundles.keep 控制保留 0~100 个历史压缩包(默认最多 3 个);upy update 升级时全自动同步 zsh、bash 与 fish 补全规则,新命令即刻生效。

一个二进制,
轻量交付。

开源(MIT 协议)。
单二进制、零外部依赖、极低内存占用。

阅读完整文档 ↗