@dsh-remote/relay 3.1.3 → 3.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/deploy/README.md +1 -1
- package/deploy/docker/Dockerfile +26 -52
- package/deploy/docker/README.md +4 -7
- package/dist/bundle/main.js +434 -356
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# @dsh-remote/relay
|
|
2
2
|
|
|
3
3
|
DSH Remote Control 的**零知识 WebSocket 中继**:在宿主插件与已配对的手机之间转发**密封记录**,
|
|
4
|
-
只认帧名 / 会话 id /
|
|
4
|
+
只认帧名 / 会话 id / 协议版本闸,**从不解析载荷**——密文对它就是一个 base64 字符串。
|
|
5
5
|
|
|
6
6
|
生产形态是**单文件产物** `dist/bundle/main.js`(`ws` / `zod` / 协议层全部内联,运行时零依赖);
|
|
7
7
|
部署只有两种:拷这个单文件 + 起进程(systemd / docker / nginx 配方见下),或从源码构建。
|
|
8
8
|
|
|
9
9
|
## 自托管
|
|
10
10
|
|
|
11
|
-
完整配方(环境变量表、systemd / docker / nginx
|
|
11
|
+
完整配方(环境变量表、systemd / docker / nginx、排错、升级)见
|
|
12
12
|
[`docs/SELF-HOSTING.md`](docs/SELF-HOSTING.md)。最速验证:
|
|
13
13
|
|
|
14
14
|
```sh
|
package/deploy/README.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
于是生产只有"拷一个文件 + 一个 env 文件",没有 `npm install`,也就没有
|
|
21
21
|
"服务器上的依赖树和 CI 不一样"这一类故障。
|
|
22
22
|
|
|
23
|
-
>
|
|
23
|
+
> 完整的环境变量表、日志契约、重启语义、升级见 [`../docs/SELF-HOSTING.md`](../docs/SELF-HOSTING.md)。
|
|
24
24
|
|
|
25
25
|
## 从零复现
|
|
26
26
|
|
package/deploy/docker/Dockerfile
CHANGED
|
@@ -41,67 +41,41 @@
|
|
|
41
41
|
# (deploy/docker/README.md 有完整的离线步骤;生产那次就是这么发的)。
|
|
42
42
|
#
|
|
43
43
|
# Node 22 与 CI、与 HANDOFF 的工具链口径一致(pnpm 11 要求 >= 22.13)。
|
|
44
|
+
#
|
|
45
|
+
# ## 2026-10-13(3.1.5 起):这份 Dockerfile 回到**单仓形态**
|
|
46
|
+
#
|
|
47
|
+
# 3.1.3/3.1.4 那两次部署用的是**伞仓上下文**(COPY 带 `packages/` 前缀、compose 的
|
|
48
|
+
# `context: ../..` 指到 monorepo 根)——因为那时服务器上摆的是整棵伞仓树。
|
|
49
|
+
# 2026-10-13 用户裁决:服务器改成**单仓部署**(部署源 = 本仓,不再摆伞仓)。
|
|
50
|
+
# 本仓与伞仓共用这份文件路径(`deploy/docker/Dockerfile`),但**两边各有一份内容**:
|
|
51
|
+
# 伞仓那份(`/deploy/docker/`)保持 monorepo 形态给伞仓构建用;本仓这份从现在是
|
|
52
|
+
# 独立仓形态——`COPY package.json pnpm-lock.yaml ./` 拷的是**本包**清单,
|
|
53
|
+
# `@dsh-remote/protocol` 从 **npm** 装(devDependency,发版顺序 protocol 先行),
|
|
54
|
+
# `pnpm-lock.yaml` 由 `scripts/split-repos.mjs` 在暂存时生成并随仓跟踪(CI 的
|
|
55
|
+
# `--frozen-lockfile` 依赖它)。两份 Dockerfile 的差异只有 build 阶段的 COPY 路径,
|
|
56
|
+
# runtime 阶段逐字相同。
|
|
44
57
|
FROM node:22-alpine AS build
|
|
45
58
|
WORKDIR /src
|
|
46
59
|
|
|
47
|
-
#
|
|
60
|
+
# 先只拷清单与锁再装:安装缓存按 lockfile 命中,改 src 不必重装依赖树。
|
|
48
61
|
# --frozen-lockfile 是刻意的——镜像里装的必须与提交的 lockfile 逐位一致,
|
|
49
62
|
# "构建时顺手升了某个传递依赖"这类漂移正是要消掉的。
|
|
50
|
-
#
|
|
51
|
-
# ## v3 单仓:这里的 COPY 必须带 packages/ 前缀(2026-10-08 修)
|
|
52
|
-
#
|
|
53
|
-
# v2 时这个仓是**独立仓**,build 上下文(compose 的 `context: ../..`)就是本仓根,
|
|
54
|
-
# 所以 `COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./` 拷的是"本包 + 本包锁"。
|
|
55
|
-
# v3 变成 monorepo 后,同一行拷的是 **monorepo 根**的三个文件——而根 package.json 里
|
|
56
|
-
# 没有 relay 的依赖,于是 pnpm 报的错是「lockfile 里有 ^22.9.0、manifest 要 ^26.6.3」
|
|
57
|
-
# 这类**看起来毫不相关**的 mismatch(真实原因:那份 package.json 不是这个包的)。
|
|
58
|
-
#
|
|
59
|
-
# 症状与判据:`docker compose build` 失败,而 `pnpm install` 在本机完全正常。
|
|
60
|
-
# 所以下面显式列出三个路径,让"上下文是单仓根"这件事变成 Dockerfile 自己保证的。
|
|
61
|
-
# ⚠️ 下面几行的行尾**不许带注释** —— Dockerfile 会把 `#` 之后的内容也当成拷贝路径
|
|
62
|
-
# (报错形态:`"/需要它要解": not found`,看起来像文件不存在,其��是把注释当路径了)。
|
|
63
|
+
# ⚠️ 下面几行的行尾**不许带注释** —— Dockerfile 会把 `#` 之后的内容也当成拷贝路径。
|
|
63
64
|
# 要说明就写在上一行。
|
|
64
|
-
COPY pnpm-workspace.yaml ./
|
|
65
|
-
COPY pnpm-lock.yaml ./
|
|
66
|
-
# monorepo 根清单:pnpm 需要它来解 workspace(里面没有 relay 的依赖,只负责解析结构)
|
|
67
65
|
COPY package.json ./
|
|
66
|
+
COPY pnpm-lock.yaml ./
|
|
68
67
|
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
# 镜像只需要 relay + protocol 的源码,但**清单必须全在场**,否则 pnpm 在 install 阶段就退出了。
|
|
75
|
-
COPY packages/relay/package.json ./packages/relay/
|
|
76
|
-
COPY packages/protocol/package.json ./packages/protocol/
|
|
77
|
-
#
|
|
78
|
-
# ⚠️ **不需要**把 workspace 里其他包(plugin / client / e2e)的 package.json 也拷进来。
|
|
79
|
-
# 我一度以为"声明的包必须清单齐备",为此加了三条 COPY —— 那三条**无效**:
|
|
80
|
-
# 删掉之后 `pnpm install --frozen-lockfile` 照样通过(2026-10-08 在服务器上实测过:
|
|
81
|
-
# 只放 protocol + relay 两份清单,frozen 检查顺利过,只在下一步因缺 protocol 的
|
|
82
|
-
# tsconfig 而失败)。pnpm 只校验**它要解析的那些 importer**。
|
|
83
|
-
#
|
|
84
|
-
# 那次「lockfile 有 ^22.9.0、manifest 要 ^26.6.3」的 mismatch 真相不是"清单没拷全",
|
|
85
|
-
# 而是**根 package.json 被污染**:上传源码时用 `tar xzf`,relay 的 package.json
|
|
86
|
-
# 覆盖到了仓库根,于是 pnpm 拿 relay 的依赖去比根的 lock ⇒ 报出 relay 的依赖名。
|
|
87
|
-
# ⇒ **报错指错地方时,先怀疑"文件被覆盖",别急着加 COPY。**
|
|
88
|
-
#
|
|
89
|
-
# protocol 的 src + tsconfig 必须在 install **之前**进来:
|
|
90
|
-
# 它的 `prepare: tsc -p tsconfig.json` 是 install 生命周期的一环,
|
|
91
|
-
# 顺序写反的报错是 `TS5058: path does not exist`,出现在 install 阶段。
|
|
92
|
-
COPY packages/protocol/tsconfig.json ./packages/protocol/
|
|
93
|
-
COPY packages/protocol/src ./packages/protocol/src
|
|
68
|
+
# `@dsh-remote/protocol` 是 devDependency、从 **npm** 装(不再是 workspace 软链):
|
|
69
|
+
# 单仓里没有它的源码,也不需要——它对 runtime 是零依赖(bundle 全内联)。
|
|
70
|
+
# 发版顺序因此必须是 **protocol 先发**,本仓构建才能锁到同版本。
|
|
71
|
+
# 锁文件由 `scripts/split-repos.mjs` 暂存时 `pnpm install` 生成并随仓跟踪;
|
|
72
|
+
# 在伞仓里它不存在(伞仓由根锁文件管),这是"两边各有一份内容"的一部分。
|
|
94
73
|
RUN corepack enable && pnpm install --frozen-lockfile
|
|
95
74
|
|
|
96
|
-
COPY
|
|
97
|
-
COPY
|
|
98
|
-
COPY
|
|
99
|
-
#
|
|
100
|
-
# 而 bundle 脚本按 node_modules 解析 ⇒ 拿到的必须是 `dist/src/**`(main 字段指向那里)。
|
|
101
|
-
# 少这一步的报错形态是 esbuild 找不到 `@dsh-remote/protocol/dist/src/index.js`。
|
|
102
|
-
RUN pnpm --filter @dsh-remote/protocol build
|
|
103
|
-
# 在 relay 包目录里构建:它的 tsconfig 与 bundle 脚本都以包根为基准
|
|
104
|
-
WORKDIR /src/packages/relay
|
|
75
|
+
COPY tsconfig.json ./
|
|
76
|
+
COPY src ./src
|
|
77
|
+
COPY scripts ./scripts
|
|
78
|
+
# tsconfig/bundle 脚本都以仓根为基准(单仓形态:仓根就是包根)
|
|
105
79
|
RUN pnpm build
|
|
106
80
|
|
|
107
81
|
# 产物级断言。两条取自 tests/bundle.test.mjs 的同款断言,写在这里是因为
|
|
@@ -119,7 +93,7 @@ ARG VCS_REF=unknown
|
|
|
119
93
|
LABEL org.opencontainers.image.title="dsh-remote-relay" org.opencontainers.image.description="Zero-knowledge WebSocket relay for DSH Remote Control" org.opencontainers.image.source="https://github.com/providcc/dsh-remote-server" org.opencontainers.image.licenses="MIT" org.opencontainers.image.version="${DRC_VERSION}" org.opencontainers.image.revision="${VCS_REF}"
|
|
120
94
|
|
|
121
95
|
WORKDIR /app
|
|
122
|
-
COPY --from=build /src/
|
|
96
|
+
COPY --from=build /src/dist/bundle/main.js /app/relay.mjs
|
|
123
97
|
|
|
124
98
|
# 只有这两个。**故意不设 DRC_STATE_FILE**:镜像里的默认值要与裸机(systemd 单元)一致——
|
|
125
99
|
# 不配就是纯内存、配了才落盘。落盘路径属于"部署形态"而不是"程序形态",它与卷是一对,
|
package/deploy/docker/README.md
CHANGED
|
@@ -57,20 +57,17 @@ docker compose … logs relay | jq 'select(.msg=="counters")'
|
|
|
57
57
|
json-file 轮转(`max-size: 10m` / `max-file: 5`)。要长期留存就装一个日志驱动转发出去,
|
|
58
58
|
别依赖 `docker logs`。
|
|
59
59
|
|
|
60
|
-
##
|
|
60
|
+
## 升级
|
|
61
61
|
|
|
62
62
|
```sh
|
|
63
63
|
# 升级:构建 → 重启 → 看版本号变了没有
|
|
64
64
|
docker compose -f deploy/docker/compose.yaml up -d --build
|
|
65
65
|
curl -s http://127.0.0.1:8787/healthz | grep -o '"version":"[^"]*"'
|
|
66
|
-
|
|
67
|
-
# 回滚:把标签切回去再 up(镜像还在本地)
|
|
68
|
-
docker tag dsh-remote-relay:2.0.14 dsh-remote-relay:2.0.15
|
|
69
|
-
docker compose -f deploy/docker/compose.yaml up -d
|
|
70
66
|
```
|
|
71
67
|
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
三端(中继 / 宿主插件 / 小程序)必须升到**同一协议版本**:落后的一端会在 `hello` 那一刻
|
|
69
|
+
被明确拒掉(`unsupported_protocol`)。⚠️ 2026-10-11 晚:原来这里还写着一套"成对回滚 +
|
|
70
|
+
两代兼容矩阵",随能力位与版本协商机制一起删掉了 —— 没有老用户,不需要回滚路径。
|
|
74
71
|
|
|
75
72
|
## 拉不到 Docker Hub 怎么办
|
|
76
73
|
|