# @frontierjs/outpost 中文文档

规范地址：https://npmcn.com/package/%40frontierjs/outpost/

版本：0\.1\.13
npm 元数据更新时间：2026-11-06T08:07:22.455Z
中文译文更新时间：2026-11-15T17:36:38.122Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40frontierjs/outpost
原文对照：https://npmcn.com/package/%40frontierjs/outpost/?lang=original
源码仓库：https://github.com/frontierJS/frontierjs

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：316 kB，20 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- 运行依赖：2 个
- 首次发布：2026-09-13T05:55:08.670Z
- 最新版本发布：2026-11-06T08:07:22.084Z
- 近 30 天下载量：2021（2026-10-16 至 2026-11-14，npm 官方下载统计）
- 已发布版本数：12（近 12 个月 12 个）

## 中文简介

车队服务器运行的过程——Basecamp的手放在机器上

## 安装

```sh
npm install @frontierjs/outpost
```

也可以使用：`pnpm add @frontierjs/outpost`、`yarn add @frontierjs/outpost`、`bun add @frontierjs/outpost`

## README

# @ frontierjs/ 张贴

**车队服务器运行的过程 .** Basecamp是控制平面,这是它的 双手放在机器上 1个 `Server` 行数`FJS-D29` - 基础设施正在建设 名词,它做两件事,没有别的:

-   **回答命令** ——拉动,建设,部署,停站,健康检查,执行,普鲁纳 他们中每一个都签了字;
-   **报告** - 心跳 说在哪里到达它,机器的 卷和磁盘在较慢的时钟上.

这不是FJS的申请。 它的任务是运行 Docker 命令并报告 健康,一个FJS应用 将设置一个计划,一个迁移跑道和一个ORM 每个舰队服务器都会这么做.

## 运行一个

```sh
OUTPOST_SERVER_ID=<the Server row's id> \
OUTPOST_SIGNING_KEY=<this machine's private key> \
OUTPOST_HUB_KEY=<Basecamp's public key> \
BASECAMP_URL=https://basecamp.internal \
OUTPOST_TLS_CERT=/etc/outpost/outpost.crt \
OUTPOST_TLS_KEY=/etc/outpost/outpost.key \
bunx --bun @frontierjs/outpost
```

这六个国家没有违约,没有违约程序就无法启动。 一个 不能将其服务器报告命名为无名报告的外出站 。 一个没有中枢键 要么拒绝每一个命令 要么接受每一个命令 两把钥匙都来自 注册:机器使自己的Ed25519对和Basecamp记录 公开一半,然后回答自己的问题,每个命令都根据 (单位:千美元)`FJS-D1604`) (中文(简体) ). 命令端口服务 仅限TLS. 它的证书是自签名的( E)`ensureCert` 内 `@frontierjs/outpost/cert`),在入学交换中被送往Basecamp 被困在那里,所以一个命令到达没有端口持有任何其他(`FJS-D557`) (中文(简体) ). 其它东西都有 默认 - `OUTPOST_PORT` (8180 dev, 7180测试) - 数字来自 `packages/cli/core/ports.js`,项目编号8), `OUTPOST_PUBLIC_URL`, (中文(简体) ), `OUTPOST_HEARTBEAT_MS`, (中文(简体) ), `OUTPOST_REPORT_MS`, (中文(简体) ), `OUTPOST_WORK_DIR`, (中文(简体) ), `OUTPOST_RESTORE_DIR` (单位:千美元)`/var/lib/outpost/restore`,唯一的目录 `/volume/restore` 读取一个档案从, `OUTPOST_BACKUP_DIR` (单位:千美元)`/var/lib/outpost/backups`时 `/backup` 写一个, `OUTPOST_DEPLOY_KEY_DIR` (单位:千美元)`/var/lib/outpost/deploy-keys`,每个应用程序的部署 键,一次制作,从未发送; `FJS-D1555`)和四个 属于静态的半个 `OUTPOST_STATIC_DIR`, (中文(简体) ), `OUTPOST_STATIC_PORT` (8181 dev,7181测试; `0` 关掉它) `OUTPOST_STATIC_URL` - 和 `OUTPOST_CADDY_ADMIN`该机器的凯迪管理员API(`http://127.0.0.1:2019`, (中文(简体) ), 哪个 a `/deploy` 名称 `hosts` 推动它的路线。 没有凯迪的机器 部署一个没有前作主机名的应用程序 .

在盒子上一个Basecamp运行, `fli deploy` 还写 `OUTPOST_HOST_DB_PATH` 财务报告和审定财务报表 `OUTPOST_HOST_ENV_PATH`: 数据库目录和文件持有 `ENCRYPTION_KEY`。 。 。 . `posture()` 然后输入数据 `host_files`,哪个 `/hub/security/` 年级。 没有其他的机器可以设置它们.

`OUTPOST_PUBLIC_URL` 因为这个过程不能 看世界的地址,它到达它。 这一定是 `https`和进程 basecamp没有为普通数据库登记目标。 这就是心跳记录的 basecamp 拒绝所有释放 机器——有一条信息这样说,而不是一无所获的绿色部署.

## 脱了一条

安装( Basecamp ) `installScript()`)写作 `/usr/local/sbin/outpost-uninstall` 所以盒子里有它自己的回路 不管发生了什么 Basecamp的注册. `sudo outpost-uninstall` 删除外站、 其 证书,它的防火墙和Litestream单元, 并留下它放置的应用程序 运行, 未复制 . `--purge` 也删除这些应用程序和每个 Docker 音量,则, `/var/lib/outpost` 和它的后援,多克,凯迪, 和他们合适的来源, litestream 二进制,出站程序目录和出站包. 它请您输入 `purge`,或采取 `--yes` 当有没有终端。 两者 最后列出他们故意留下的东西: sshd倒入(删除它可以) 恢复密码登录、chrony、安全更新和服务器行, 在Basecamp待到有人把它搬走为止.

## 协议

大本营到达它 `outpost:<server-id>` 超过康迪特。 每一个路线,但是 `GET /health` 需要签字; `/exec` 运行此 shell 命令 进程用户,所以默认是拒绝,一个路由选择退出而不是加入.

|  |  |
| --- | --- |
| `POST /pull` | `{ image }` → `{ digest }` |
| `POST /deploy` | `{ deployment_id, app_id, image, digest, source, config }` → `{ containerId, digest, commit_sha }`· ; `config` 实值 `port`, (中文(简体) ), `containerPort`, (中文(简体) ), `volumePath`, (中文(简体) ), `cpuLimit` (单位:千美元)`--cpus`, (中文(简体) ), `memLimitMb` (单位:千美元)`--memory`, (中文(简体) ), `env` 财务报告和审定财务报表 `logs` |
| `POST /build` | `{ app_id, source, image }` → `{ digest, commit_sha, dockerfile, exposed_port }`; 以应用的部署密钥克隆, 并使用 `source.dockerfile` (App的存储副本) 当给,否则 `deploy/Dockerfile`,则 `Dockerfile`· ; `exposed_port` 这是最后一个文件 `EXPOSE`,当没有人说时无效;a `deploy/Dockerfile` 没有 `deploy/generated/` 拒绝命名 `fli deploy:vendor` (单位:千美元)`FJS-D942`(中文(简体) ) |
| `POST /deploy-key` | `{ app_id }` → `{ app_id, public_key }`;该应用软件的ed25519 键在第一次询问时制作并保存. 每一个心跳都带着他们 `deploy_keys: [{ app_id, public_key }]` |
| `POST /source/file` | `{ app_id, path }` → `{ path, content }`; 一个文件(最多64 KB) 离开应用程序的最后一个克隆, `content: null` 当克隆人没有这样的文件时; 拒绝在此建立从未创建的应用程序, 拒绝在克隆人之外引导路径或符号链接 |
| `POST /stop` | `{ app_id }` → `{ stopped, unrouted }` |
| `POST /site/preview` | `{ app_id, source, branch, alias, cloudflare: { token, account_id } }` → `{ commit_sha, url, version_url }`; 树枝头被安装, 与 `site-kit build --preview` 并上载为别名的工人版本 `alias`在丢弃的容器中的每一步骤,随后取出; `commit_sha` 是建造的,它可能比召唤者所见的更新 |
| `POST /site/publish` | `{ app_id, source, branch, commit, cloudflare: { token, account_id }, app?: { volume_path, env } }` → `{ commit_sha, url, skipped? }`; 与 `site-kit build` 财务报告和审定财务报表 `site-kit deploy`,现场 `branch` 已经不在 `commit`与 `app`一个API App的 `site/`数字 : `sierra site --deployed` 首先,建设对一个 `litestone backup` 联 合 国 `fjs-<app>`数据库与 `env` 作为它的变数, `sierra site --deploy`; 无 `site/` 或者没有部署答案 `skipped` (单位:千美元)`FJS-D1689`(中文(简体) ) |
| `POST /route` | `{ app_id, hosts, port? }` → `{ hosts, port, rebind }`;该应用程序的凯迪路由被替换,或为没有主机而去掉,拨打已发布的运行的容器端口. `rebind` 当束缚不再匹配时, 是句子, 只有下一个 `/deploy` 变化。 已声明 `port` 用于一个没有容器的应用程序——这个机器上的预览版的dev服务器——并且被拒绝了 |
| `POST /health-check` | `{ app_id, port, path }` → `{ healthy }`附加时 `reason` 当它不是 `path`跑步还不够 `127.0.0.1:<port><path>` 必须回答 2xx |
| `POST /exec` | `{ command, timeout_s }` 或者说 `{ step }` → `{ exit_code, stdout, stderr }` |
| `POST /logs` | `{ app_id, tail, since }` → `{ running, tail, since, stdout, stderr }`附加时 `error` 当没有这种容器时 |
| `POST /analytics` | `{ route_id, from, to }` (UTC瞬间结束) `Z`,每个可选) `{ route_id, from, to, files, lines, skipped, truncated, oldest, kept_since, hosts: [{ host, requests, bytes, client_ips, status, paths, errors, durations }] }` —— 说 `client_ips` 与众不同 `request.client_ip`s,绝不是人;路径会丢弃查询;每个面板会回答其前20名,并且读取最先解析出10万行的最新数据(`truncated`, (中文(简体) ), `oldest` 说在哪里被剪; `kept_since` 是卷所保存的最古老文件的第一行, 不论窗口如何; 从路由的凯迪访问日志及其滚动文件中计出; 没有日志的路由会被名字拒绝 |
| `POST /static/publish` | `{ app_id, files }` → `{ digest, files, bytes }` ——写出,尚未活出 |
| `POST /static/activate` | `{ app_id, slug, digest }` → `{ digest, host, url }` |
| `POST /static/health` | `{ app_id, digest }` → `{ healthy, digest }`附加时 `reason` 当它不是 |
| `POST /static/retire` | `{ app_id, slug }` → `{ retired }` ——停播,每次发行都保留 |
| `POST /static/releases` | `{ app_id }` → `{ current, digests }` |
| `POST /ingress` | `{}` → `{ caddy, listen, routes: [{ id, hosts, to }], servers }` -凯迪的 `ingress` 服务器路线,无论是谁写的,每条路线缩小到目的地; `servers` 列出每个其它的 http 服务器( 在 : 443 上的第二个是 Caddy 文件, 仍在运行); `caddy: false` 在一台没有一台的机器上 |
| `POST /system/prune` | `{ targets, keep_images }` → `{ freed_bytes, removed, volumes, usage }` |
| `POST /volumes/prune` | `{ names }` → `{ removed }` |
| `DELETE /volumes/<name>` | → `{ removed }`,或409,并装有容器 |
| `POST /backup` | `{ app_id, upload_url? }` → `{ volume, path, bytes, files, sha256, uploaded?, upload_error? }`· ; `fjs-<app>-data` 焦油 (gzip) 为 `OUTPOST_BACKUP_DIR` 被一个只读出音量的被扔出容器。 档案保存在机器上,答案是它的路径和文摘. 与 `upload_url`,一个预先签名的PUT Basecamp 刻出,档案从出站程序流到它 `uploaded` 说它是否降落, `upload_error` 机器没有桶钥匙。 拒绝量 机器没有 |
| `POST /backup/send` | `{ app_id, path, upload_url }` → `{ bytes, sha256 }`; 一个归档 `/backup` 保存, PUT 到一个预先签名的 URL Basecamp 薄荷 (它下载了一个机器- kept 存档) . `path` 一定是个 `<app_id>-*.tar.gz` 直接下方 `OUTPOST_BACKUP_DIR`以及一个没有降落的PUT |
| `POST /volume/restore` | `{ app_id, path | url + sha256, overwrite?, per_file? }` → `{ data_dir, archive, files, bytes, overwrite, per_file, sha256? }`; 焦油 (gzip 或不) 下方 `OUTPOST_RESTORE_DIR`,被提取到应用程序的数据目录中。 与 `url`,一个预签名的 GET Basecamp minted, 存档会先到那里取出并拒绝, 除非它的sha256匹配; 副本会在之后取出 。 在任何容器持有目录时被拒绝,并输入带有文件的目录,除非 `overwrite: true`先把它空出来 与 `per_file: true` (包头) `.db`, (中文(简体) ), `FJS-D1724`每个顶级 `.db` 替换它自己的文件以及该文件的 `-wal`编号 :`-shm`剩下的留下来 `overwrite` 每个数据库都要求 |
| `POST /replica/restore` | `{ app_id, replica, databases, at?, overwrite? }` → `{ volume, files, bytes, overwrite, databases, replication }`;每个被命名的数据库恢复出应用程序的Litestream复制品, at `at` 或最近的,只替换 `.db` 在已停止的音量中的文件; Litestream 已重新启动, 以便取出它们 |
| `POST /replica/drill` | `{ app_id, replica, databases, at?, image, digest?, env }` → `{ databases, verified, verify }`;每个被命名的数据库从复制品中恢复为中转目录,从不包含音量,然后 `litestone restore --verify-only` 运行在应用自己的形象(`--network none`, (中文(简体) ), `env` 姓名; `verified: false` 是一个200个报告,一个不回答报告的图像是500个(`FJS-D1524`(中文(简体) ) |
| `GET /health` | 没有签名的活生生的——没有说机器 |

**签名是 `@frontierjs/toolbelt/signature`** - 相同的模块管道 和Basecamp核实。 方法、路径、时间戳、非ce和散列 因此无法重放一个抓取的签名,移动到另一个 结束点,或者在身体被交换时保存.

## 字节从哪里来

V1以目标为基础:a `source.kind === 'git'` 部署克隆、构建和 回答关于它所构建的, Basecamp 记录在 `Deployment.builtImage` 并逐一处理。 老实说 外出站与Basecamp——一机相通,CapRover形状相通. 这个 最终状态是一站式建设 推动-开发-开发, 需要一个建设者 把动画: `IDEAS/deploy-plane.md`。 。 。 .

**仅 `sha256:<64 hex>` 算作一个摘要.** 标签是一个名字, 和两个建筑 分享它 — 一个图像检查, 回答其他任何问题, 报告为没有摘要 而不是一个可信的.

### 或者字节是应用

一个应用 `source.kind` 实值 `inline` 没有寄存器和图像 : 文件 自我释放 从CDN装入React的一页是一个完整的应用程序, 这里没有东西可以建造. `POST /static/publish` 将文件写入 以自己的sha256和 `POST /static/activate` 换一个 symlink——这就是为什么一个相同的字节重排来回答同样的文摘, 以及为什么回滚一无所获.

文摘在此计算,打电话者不表示: 运行,关于发送的字节的声称 不是读取字节 着陆了 每个路径都是普通文件名称的允许列表,文件是 写入一个中程目录并移动到一个位置 `rename`,所以一个 发布中途死亡时,不能让发布中保存一些自己的文件.

**他们在自己港口的第二位听众中服役** (单位:千美元)`OUTPOST_STATIC_PORT`) (中文(简体) ). 网页是由谁可以编辑一个应用程序的人撰写的,所以他们能达到的任何东西都是 同一来源是他们的——一个港口是一个来源,所以与签名的港口共用一个 命令协议将把舰队放入每个原型机 没什么 端口是签名或认证的:它是公共文件的网络服务器,并且 只能读取它能表演的 在一个发行目录中 。 它会束缚回转 和 Caddy 按主机名进行前置(`FJS-D1459`),因此是一个没有主机名的内置应用程序 单从机器到达。 应用程序的首个标签是 东道主( E)`shop.fleet.example.com`)或由第一个路径段(`/shop/`) (中文(简体) ).

## 测试

`bun run test` 没有Docker和网络. `createDocker({ run })` 带上跑者 `createReporter({ fetch })` 带走客户,那么什么是 据称,机器是 " ASKED " 所要做的事情和留下的程序。 A 类 只能对真实守护进程进行测试的软件包 和错误的.

## 常见问题

### @frontierjs/outpost 是什么？

车队服务器运行的过程——Basecamp的手放在机器上

### 如何安装 @frontierjs/outpost？

在项目目录运行 npm install @frontierjs/outpost，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 outpost，可以用 npx outpost 直接运行。

### @frontierjs/outpost 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/frontierjs\_\_outpost 是否存在。

### @frontierjs/outpost 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @frontierjs/outpost 可以商用吗？

@frontierjs/outpost 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @frontierjs/outpost 的下载量有多少？

根据 npm 官方下载统计，@frontierjs/outpost 在 2026/10/16 – 2026/11/14 这 30 天内被下载 2,021 次，日均约 67 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @frontierjs/outpost 还在维护吗？

最新版本 0\.1\.13 发布于 2026/11/06（9 天前）；至今共发布 12 个版本，其中过去 12 个月发布了 12 个；首次发布于 2026/09/13。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

