# 部署中继网关

给运营方：一台云服务器、一个域名、一行命令，大约 10 分钟装好一台 TapeRelay 中继网关；装好以后用一个菜单管理。

- 网页版的部署指南（新手指引、生成命令、查解析、从外面检查，中英两种语言）：<https://taperelay.com/>
- 让 AI 助手代你部署：见 [AI 部署手册](DEPLOY-FOR-AI.md)
- 出了问题：先在服务器上运行 `sudo taperelay-node doctor`，再看 [排查手册](TROUBLESHOOTING.md)

## 一、准备三样东西

| | 要求 |
|---|---|
| 云服务器 | 常见的 Linux 服务器系统（x86_64 或 ARM）：Ubuntu 22.04 以上、Debian 12 以上、红帽 9 一族（Rocky、AlmaLinux、CentOS Stream、RHEL、OpenCloudOS 9 等）、Fedora、Amazon Linux 2023 直接装；更旧的（Ubuntu 20.04、Debian 11、红帽 8 一族、CentOS 7 等）安装程序会改用 Docker 装（见下面「系统太旧时」）。1 核、1 GB 内存起步（服务本身最多用 512 MiB，I-362；内存不到 2 GB、又没有交换空间时，安装程序加 1 GB 交换空间）；硬盘至少空 3 GB，要加交换空间的至少 4 GB（服务器剩得不到 2 GB 就不收新的上传，I-309、I-316），按要给用户的空间准备；有公网 IP、能用 sudo；要一台普通的云服务器（不能在 Docker 容器里面装） |
| 域名 | 在域名服务商加一条 A 记录，指向服务器的**公网** IP（云控制台里叫「公网 IP」或「弹性 IP」，不是 10.x、172.16～31.x、192.168.x 这类内网地址）。用 Cloudflare 的要关掉代理（灰色云「仅 DNS」）：客户端按普通网站的规则直接校验证书 |
| 端口 | 在云服务商的安全组 / 防火墙里放行 TCP 80、443、4246 入站。4246 是协议的专用端口，443 备用（有的网络只放行 443），80 只用来申请证书、把不加密的请求跳到 HTTPS |

TapeRelay 要独占这三个端口，用一台干净的服务器最省事。

## 二、安装

用 SSH 登录服务器，运行：

```
curl -fsSL https://taperelay.com/install.sh | sudo bash
```

它先检查服务器，再问 3 个问题（域名、运营方名字、联系方式；直接回车用括号里的），确认一次就开始装，大约 1 分钟。域名还没解析好的，可以先装着：解析对了以后证书会自动申请。想先看看脚本写了什么，用浏览器打开上面的网址就行。

不想回答问题，就把答案写在后面；给脚本、AI 用的再加 `--yes`（不问、不确认）：

```
curl -fsSL https://taperelay.com/install.sh | sudo bash -s -- \
  --domain relay.example.com --name '我的中继' --contact me@example.com --yes
```

| 选项 | 意思 |
|---|---|
| `--domain <域名>` | 例如 `relay.example.com`（不能是 IP） |
| `--name <名字>` | 运营方名字，用户在说明页里看到（默认就是域名） |
| `--contact <联系方式>` | 邮箱、Telegram 等，用户看得到；可以不填 |
| `--quota <大小>` | 每个容器默认的配额，例如 `5GB`（默认 5GB；`0` 表示不限） |
| `--admin <容器>` | 管理员容器：名字（例如 `4246.0.tape`）或地址（`eip155:56:0x…`），可以写多次；用来在前端的运营方页管理 |
| `--yes` | 不问、不确认。没有终端时必须加；新装还要 `--domain` |
| `--json` | 最后在标准输出打印一行 JSON 结果（过程写到标准错误），格式见 [AI 部署手册](DEPLOY-FOR-AI.md) |
| `--no-list` | 不列进官方的运营方名单（默认装好后服务器自己上报、列进去，官方前端的用户能看到你；以后 `sudo taperelay-node set list on\|off` 改） |
| `--no-stats` | 不公开这台每天的请求数、访客数、发出的字节数（默认公开在 `https://你的域名/v1/stats/gateway`，只有合计、不存访客的地址；以后 `sudo taperelay-node set stats on\|off` 改）。一步一步问的时候，名单、统计这两样都会直接问你 |
| `--local-ca` | 证书由 Caddy 自己签：只用于没有公网域名的测试机（不上报名单） |
| `--profile <配置名>` | `default`（默认）、`test-1`、`test-2`：官方的两台测试服务器用 |
| `--docker` | 用 Docker 装（系统太旧、直接装不了时安装程序会自己问，不用加） |
| `--registry-mirror <地址>` | Docker Hub 的镜像加速地址（例如阿里云「容器镜像服务」给的 `https://xxxx.mirror.aliyuncs.com`）；只在 Docker 是这次安装程序装的时候写进 Docker 的设置 |

退出码：`0` 装好了、体检全过；`2` 装好了、体检有不过的项（多半是域名解析或云防火墙：照提示改，不用重装）；`1` 没装成（原来的程序和配置都没动）。详细记录在 `/var/log/taperelay-install.log`。

### 服务器下载不了安装包

在自己的电脑上打开 <https://taperelay.com/download> 下载最新的 `taperelay-<版本>.tar.gz`（核对用的 SHA-256 在 <https://taperelay.com/SHA256SUMS>，部署指南的「离线包」里也写着），传到服务器上运行包里的安装程序：

```
scp taperelay-*.tar.gz ubuntu@<服务器>:~
ssh ubuntu@<服务器>
tar -xzf taperelay-*.tar.gz && sudo bash taperelay-*/install.sh
```

Node.js 先从 nodejs.org 下载，下不了换 npmmirror.com 的镜像，都按安装程序里写好的 SHA-256 核对；Caddy 一律用它在 GitHub 上发布的官方程序（固定版本，按安装程序里写好的 SHA-512 核对；2026-10-25 起 Ubuntu、Debian 也这样，原来从它的官方软件源 dl.cloudsmith.io 装，软件源的钥匙和配置都不核对，I-332）。出包时 Node.js 的 SHA-256 与仓库里钉住的（`deploy/node-sums.json`）对照，不同就不出包。

### 系统太旧时：用 Docker 装

Node.js 26 的官方程序要系统的 C 库（glibc）是 2.34 以上：Ubuntu 20.04、Debian 11、红帽 8 一族（Rocky 8、AlmaLinux 8、阿里云 Linux 3、OpenCloudOS 8、龙蜥 8 等）、CentOS 7、Amazon Linux 2 都太旧。在这些系统上运行同一行命令，安装程序会先说明，问过再改用 Docker 装同一个版本：

1. 没有 Docker 的，说明要装什么、从哪里装，问过再装：Docker 的官方软件源 download.docker.com，连不上换阿里云的镜像 mirrors.aliyun.com/docker-ce（同一套签名的软件包；签名钥匙先按安装程序里写的 SHA-256 核对，对不上就不装）；装好开机自动启动。红帽 7 一族（CentOS 7、RHEL 7、Oracle Linux 7、阿里云 Linux 2、TencentOS 2 等）用 Docker 给 CentOS 7 的软件源、yum 装，系统自带的软件源要能用（CentOS 7 原来的地址已经关了，大多数云服务器换好了镜像，装不上时见 [排查手册](TROUBLESHOOTING.md)）；Amazon Linux 2 用 Amazon 自己的 docker 软件包，再从 GitHub 下载 docker compose、buildx 两个插件（版本和 SHA-256 写在安装程序里，对不上就不放；还没有在 Amazon Linux 2 上实测）。别的系统（openSUSE、Arch、Alpine 等）安装程序不替你装 Docker：照 Docker 的说明先装好，再加 `--docker` 运行。Debian 11 已经停止支持，它的安全更新搬到了 archive.debian.org，装不上时见 [排查手册](TROUBLESHOOTING.md)；
2. 要从 Docker Hub 拉 Node.js、Caddy 的官方镜像。国内的服务器常常拉不到：加 `--registry-mirror <加速地址>`（阿里云控制台「容器镜像服务 › 镜像加速器」里给的专属地址）。拉不到时安装程序会提示怎么加；
3. 镜像在服务器上就地构建，用的是安装程序已经核对过 SHA-256 的同一个安装包；
4. 数据、配置、备份的位置与直接装的相同（`/var/lib/taperelay`、`/etc/taperelay`、`/var/backups/taperelay`），证书在 `/var/lib/taperelay-caddy`；
5. 装好以后照样用 `sudo taperelay-node`，命令、菜单都相同：状态、体检、改设置、看记录、备份恢复、升级、退回、卸载。不同的只是背后：服务是三个容器（`taperelay-net` 占着网络和端口、`taperelay-server` 参考服务器、`taperelay-caddy` HTTPS），运维程序在一个用完就删的容器里跑；升级、退回、卸载在服务器上直接做（卸载不删 Docker 本身）。

系统新、也可以直接装的，想用 Docker 就加 `--docker`。已经用一种方式装了的，再运行安装程序（升级）照原来的方式。

已经过了官方常规维护期（一般收不到安全补丁了）的系统照样装：CentOS 7、8，RHEL、Oracle Linux 7，阿里云 Linux 2，Amazon Linux 2，Ubuntu 20.04 及更早，Debian 11 及更早（名单只列服务器上常见的；Ubuntu 的非长期支持版等过了期的也照样装，只是不提醒）。安装程序检查时写明，装完再醒目地提醒一次；服务器公开在网上，以后发现的系统漏洞多半不会再修（另外付费买了延长支持的除外），建议尽早换到还在维护的系统（例如 Ubuntu 24.04、Debian 13、Rocky Linux 9），装法相同（D-489）。Debian 12 的常规维护 2026-07-11 结束，之后由社区的长期支持（LTS，不收费）接着出补丁到 2028-06-30，所以不算；新装的话选 Debian 13。

### 安装程序做的事

1. 检查：系统和机器类型、内存、硬盘、三个端口空不空、公网 IP、域名解析到哪里。端口被别的程序占着（包括别人在用的 Caddy）就停下，不接管、不覆盖别人的网站；这台原来装了 Caddy、但没占着这几个端口的，安装程序会用它，先把原来的配置另存为 `/etc/caddy/Caddyfile.before-taperelay`，卸载时放回去、照装之前的样子开着或停着（2026-10-24，I-302、I-308）。Caddyfile 里有 TapeRelay 的标记才算安装程序自己写的：运营方把它换成了自己的网站、Caddy 又占着端口的，升级时也停下；Caddy 没在占着端口的（例如卸载后运营方自己换了配置再装），照「装之前就有的」处理，卸载过再装的按这一次装之前的样子记（I-317）。硬盘：新装至少 3 GB（要加交换空间的 4 GB）；升级只要放得下升级前的备份、核对用的数据库副本和新程序（数据库的两倍加 500 MB），剩得不到 2 GB 只提醒（I-316）；
2. 基础软件；内存小时加交换空间；
3. Node.js（核对 SHA-256；只给 TapeRelay 用，链接在 `/opt/taperelay/node`，不换系统的 `node`）、Caddy；
4. 程序装到 `/opt/taperelay/current`（安装包自带 TapeKit 内核和依赖，不在服务器上运行 npm）；配置先生成，再用服务器自己的代码、`caddy validate` 核对，都通过才写；
5. systemd 服务：以系统用户 `taperelay` 运行，程序只读、只能写数据目录，出错自动重启；服务器自己的防火墙（ufw、firewalld、iptables）放行三个端口；
6. 启动；Caddy 申请证书；体检（同 `sudo taperelay-node doctor`），打印结果和下一步。

再运行一次就是升级：设置和数据都保留，先备份，新版本先在数据库的副本上核对（读不了现在的数据就不换程序），新版本起不来自动退回。比装着的旧的版本不装（确实要装加 `--allow-downgrade`）。

**发布有签名**（2026-10-24 起）：每一版的 `SHA256SUMS`（列着安装包和 `install.sh` 的 SHA-256）由 TapeOut 的发布钥匙签名（`SHA256SUMS.sig`）。装好的服务器运行 `sudo taperelay-node upgrade` 时，先用自己装着的那一版里的公钥名单核对签名、核对 `install.sh`，核对不过就不升级：发布网站被人改了，也装不进你的服务器。第一次安装照旧靠发布网站的 HTTPS；要自己核对，发布公钥的编号是 `a370ecb982de625e`（公钥 `fc43d3b7f24c3045883bf21e4dffeb36ccfd29a92fe8f85421b15d8728e9512e`），下载解开安装包后运行 `node taperelay-<版本>/TapeRelay/deploy/release-sign.mjs verify <放着 SHA256SUMS、SHA256SUMS.sig、install.sh 的目录>`。

运维命令叫 `taperelay-node`（2026-10-23 起；以前叫 `taperelay`，升级时旧名字的入口自动删掉）；服务名、系统用户、目录照旧叫 `taperelay`。

## 三、装好以后

- **说明页** `https://你的域名/`：给开发者看的这台的简介（2026-10-23 起，D-340）：你是谁、接口地址、配额、价格、支持的功能，两种做法、三步接入和常见问题，链到开发者指南；中英两种语言，内容从 `/v1/info` 读。
- **从外面检查**：部署指南网页里的「检查」，在浏览器里查解析、两个端口和 `/v1/info`。
- **菜单**：在服务器上运行 `sudo taperelay-node`，按数字选。也可以直接用命令（`sudo taperelay-node --help` 看全部）：

| 想做的事 | 命令（都以 `sudo taperelay-node` 开头） |
|---|---|
| 看状态、用量 | `status` |
| 体检（出问题先跑它） | `doctor` |
| 看记录 | `logs`（Caddy 的：`logs caddy`；加 `-f` 一直跟着看） |
| 改名字、联系方式 | `set name '我的中继'`、`set contact me@example.com` |
| 默认配额 | `set quota 10GB`（`0` 不限） |
| 收费 / 免费 | `set price https://… '一句话说明'`、`set price free` |
| 保存期限（天） | `set retention 30 90 90 90 30`：依次是没有容器再用的文件、欠费容器的文件、超出配额的容器（之后从最后传的删到不超出）、收件箱里的通知各保留几天，上传的文件至少留几天（不少于 7，不能比第 2、3 个大，只能改长、不能改短；改长时会再问一次）；可以只写前几个 |
| 收不收加密文件 | `set encrypted on`、`set encrypted off` |
| 管理员容器 | `admin add 4246.0.tape`、`admin remove …`、`admin list` |
| 给某个容器另定配额 | `quota <容器> 50GB`（写 `default` 回到默认的） |
| 下架 / 恢复一个对象 | `takedown <哈希>`、`untakedown <哈希>` |
| 存得最多的容器（超出配额的标出来） | `accounts` |
| 下载流量（每天的合计、流量最多的对象） | `traffic`（默认最近 7 天；`traffic 30` 看 30 天） |
| 换域名 | `set domain <新域名>`（用户要重新选用，慎重） |
| 列不列进官方的运营方名单 | `set list on`、`set list off`（默认列进；官方大约每 10 分钟读一次你的 `/v1/info`，名字、联系方式跟着变） |
| 公不公开每天的统计 | `set stats on`、`set stats off`（默认公开在 `https://你的域名/v1/stats/gateway`：每天的请求数、访客数、发出的字节数，只有合计） |
| 宣布退出 | `set exit 2027-03-01`（有接手方就把它的服务器名字写在后面；`set exit cancel` 撤销），见第五节 |

改设置后自动重启服务（约 2 秒）生效。名字、配额、价格、保存期限这些政策写在数据目录的 `policy.json` 里，和前端运营方页改的是同一份；`status` 写明现在生效的是哪一份。

**网页后台**：加了管理员容器以后（一步一步装时第 ④ 问就能填，D-492；或以后 `admin add`），可以用这个容器在 TapeRelay 网页前端的运营方页（官方的 `https://app.taperelay.com/TapeRelay/ui/app/operator.html`；内测期间用内测网址 `https://app.taperelay-test.duckdns.org/TapeRelay/ui/app/operator.html`；放了前端副本（`set app on`）的服务器上另有 `https://你的域名/TapeRelay/ui/app/operator.html`，默认不放就没有；2026-10-23 起用户的应用里没有到这一页的入口；装完的总结里写着网址）里看各容器的用量、下载流量、改政策、下架、宣布退出，不用登录服务器；用上面的命令效果一样。

## 四、交给用户

`sudo taperelay-node share` 生成一段话（名字、说明页、服务器名字、配额、价格、联系方式、前端的网址），发到群里、网站上。开发者看说明页和开发者指南（`https://taperelay.com/developers.html`）；只想存文件的用户不用装任何东西：

1. 打开官方前端 `https://app.taperelay.com/`，连接钱包（持有他的 TapeOut 容器的那个），打开容器；
2. 第一次打开时有四步设置：第 ① 步选运营方时勾上你这一家（名单里没有就在「另外的服务器」里填 `你的域名:4246`；建议再勾一家，文件各存一份），之后设本机口令、生成加密密钥、备份，第 ④ 步在钱包里确认一笔交易（写进容器的链上记录，付一点手续费）；以后改选在「设置 › 运营方和套餐」；
3. 之后上传、分享、收发文件都经过你的服务器。

> **前端的副本**（2026-10-25 起默认不放，I-326、D-464）：`https://你的域名/app/` 跳到官方前端。要放一份同样的前端（装的时候加 `--app`，或以后 `sudo taperelay-node set app on`）之前要知道：这份网页的代码在你的服务器上，用户在那里输入的本机口令、解开的加密私钥你都能拿到，也能请他们的钱包签名，所以副本顶部会写明这一点，用户要信得过你才会在那里用。浏览器按网址存加密私钥、「我的文件」这些本机记录，在副本里做的只存在你的网址下，你的服务器关了就找不回，副本顶部也会提醒用户先导出备份、平时用官方前端；分享出去的链接一律以官方前端开头。两台测试服务器（配置名 test-1、test-2）照旧放。

**运营方名单**：装好后服务器自己上报，官方读你的 `/v1/info` 核对连得上就列出，不用申请（D-328）；体检里的「运营方名单」一项写着在不在名单里。注册表上线后，官方前端只列出登记过、在保（交了押金、照常运营）的运营方，不能再手填名单外的服务器。登记的办法开放时公布在部署指南网站上。

## 五、升级、备份、退回、退出、卸载

| | 命令（`sudo taperelay-node …`） | 说明 |
|---|---|---|
| 升级 | `upgrade` | 从 taperelay.com 取最新版：先备份数据库和配置，换程序，新版本起不来自动退回；设置和数据都保留 |
| 备份 | `backup` | 数据库、`policy.json`、配置、Caddyfile，放在 `/var/backups/taperelay`（只有 root 能读；2026-10-23 之前的版本放在 `/var/lib/taperelay/backups`，以前的备份留在那里），只留最近 10 份。用户的文件本身很大，不在备份里：用云服务商的磁盘快照防硬盘坏 |
| 恢复 | `backup list`、`backup restore <名字>` | 备份之后的改动（新上传的记录等）会丢 |
| 退回 | `rollback` | 退回上一个版本，数据库和配置用升级前的备份 |
| 退出 | `set exit <日期> [接手方…]` | 宣布哪天（UTC）停止服务，从宣布起至少留 90 天：说明页顶部写明日期；有接手方的照常收新文件，没有的新上传一律拒绝、读取照常到那天；那天之前不得删用户的文件。`set exit cancel` 撤销。注册表上线后以注册表里的退出时间为准 |
| 卸载 | `uninstall` | 默认留着数据和配置；加 `--purge` 一起删（找不回来）。不想干了先宣布退出，到期再卸载。Caddy 是安装程序装的就停掉；装之前就有的放回原来的配置，装之前开着的照常运行、停着的停下，开不开机启动也照原样；装之前就有 Caddy、但没有配置文件的，删掉 TapeRelay 写的配置、停下 Caddy（I-308） |

## 六、服务器上的布局

```
/opt/taperelay/current/TapeRelay/   程序（只有 root 能改）；上一版在 /opt/taperelay/old
/opt/taperelay/current/TapeKit/kernel/
/opt/node-v<版本>-linux-<机器>/      Node.js（/opt/taperelay/node 是链接，只给 TapeRelay 用；2026-10-24 之前的版本另链接成 /usr/local/bin/node，升级时不动它）
/usr/local/bin/taperelay-node      运维命令
/etc/taperelay/server.json         配置（root:taperelay 640，服务只能读）
/etc/taperelay/install.json        安装时选的配置名、证书来源、列不列进名单、Caddy 是不是装之前就有的
/etc/caddy/Caddyfile               Caddy：说明页、443 和 4246 两个端口、80 跳到 HTTPS
/var/lib/taperelay/data/           数据库、对象、policy.json（只有 taperelay 能读写）
/var/backups/taperelay/            备份（只有 root 能读）
/var/log/taperelay-install.log     安装、升级的详细记录
```

用 Docker 装的（「系统太旧时」）：配置、数据、备份、安装记录的位置相同；没有 `/opt/taperelay/current` 和 Node.js，程序在镜像 `taperelay-node:<版本>`、`taperelay-caddy:<版本>` 里；另有：

```
/opt/taperelay/docker/             compose.yaml、装着的版本（version）、上一个版本（previous）、升级 / 退回 / 卸载用的 host.sh
/usr/local/bin/taperelay-node      运维命令（在一个用完就删的容器里运行同一份运维程序）
/etc/taperelay/Caddyfile           Caddy 的配置（Caddy 的容器只读挂进去）
/var/lib/taperelay-caddy/          Caddy 的证书等（只有 root 能读）
```

服务器上不放任何密钥：正式模式用不到；证书的私钥由 Caddy 保管，我们的代码碰不到。

许可证：代码 MIT（安装包里的 `TapeRelay/LICENSE`），规范 CC0。
