Ubuntu 22.04 安装 Hoppscotch 2026.9.0 指南

Ubuntu 22.04 裸机部署 Hoppscotch 2026.9.0 全流程实测:Node.js 24 + pnpm 10 + PostgreSQL 16 + 后端编译 + 前端构建 + Caddy 托管 + systemd 双服务,含 Node 20 编译失败、start:prod 路径不符、/v1/health 404 等排障结论。

HoppscotchHoppscotchAPI 测试Postman 替代Node.js2026/10/27

Ubuntu 22.04 安装 Hoppscotch 2026.9.0 指南

目标:在一台 Ubuntu 22.04 服务器上,从零完成开源 API 开发生态 Hoppscotch 2026.9.0 的裸机部署——Node.js 运行时、PostgreSQL 数据库、后端编译、前端构建、systemd 托管与验证回显全流程。全部命令与回显于 2026-10-27 在 Ubuntu 22.04.5 LTS(6 vCPU / 18 GB)实测,产品定位与竞品对比见《Hoppscotch 2026.9.0 介绍与选型指南》。

一、环境信息

本章交代本次实测的软件基线、目录与端口规划,后续章节的命令均以此为上下文。

项目实测值说明
操作系统Ubuntu 22.04.5 LTS(x86_64)目标发行版
Hoppscotch2026.9.0(2026-09-30 发布)官方源码包,本地编译
Node.jsv24.22.1官方构建脚本要求 nodejs>=24.18.1
npm / pnpm11.19.1 / 10.34.5pnpm 版本来自仓库 packageManager 字段
PostgreSQL16.15(PGDG jammy 源)官方示例兼容 15/16
静态前端服务Caddy v2.11.7负责 SPA 路由回退与 gzip
部署根目录/opt/hoppscotch源码、.env、Caddyfile 均在此
后端端口8121NestJS API + GraphQL
前端端口8122构建产物静态托管
系统账号root / q1w2e3r4实验服务器演示账号
数据库账号hoppscotch / q1w2e3r4库名同账号名

端口规划只保留两个对外入口:8122 给浏览器,8121 给前端页面里的 API 与 WebSocket 调用。管理台(hoppscotch-sh-admin)与桌面端 bundle server 属于独立包,本指南不纳入最小可用部署。

⚠️ 网络说明:实测时 npm 官方源 registry.npmjs.org 单包下载速度仅 3–19 KiB/s,PGDG 源 apt.postgresql.org 亦长期停在 13 MB 未完成,两者均改用内网代理 192.168.1.62:7897 后才完成。当前实测可用渠道为「内网代理」,官方源可直连但速度不可用。

二、前置条件

开始前确认以下四项,缺一项都会在中途失败。

  1. 系统与权限:Ubuntu 22.04,具备 root 或 sudo;本文命令以 root 执行。
  2. 资源:实测 node_modules 占 1.4 GB、前端产物 124 MB,建议至少 4 vCPU / 8 GB 内存 / 20 GB 磁盘余量。前端构建脚本自身申请 8 GB 堆上限,内存过小会 OOM。
  3. 数据库:PostgreSQL 15 或 16 均可,本指南装 16。后端不在首次启动时建库,必须先手工建库建账号。
  4. 出网:需要访问 Node.js 官方分发站、npm 源、PGDG 源与 GitHub 发布件;国内网络下按上文代理方案处理。

先确认系统版本与端口空闲:

cat /etc/os-release | head -3
ss -lnt | grep -E '8121|8122' || echo "8121/8122 均空闲"

实测回显:

PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
8121/8122 均空闲

三、版本与运行环境选型

这一节解释三个容易被教程带偏的选择,都是本次实测踩出来的。

3.1 Node.js 必须 24,不能用 20

任务书与多数旧教程写的是「Node 20+」,但 2026.9.0 的 isolated-vm@6.1.2 在 Node 20.20.2 上会现场编译并失败:

../src/isolate/holder.h:56:22: error: 'void ivm::IsolateTaskRunner::PostDelayedTaskImpl(std::unique_ptr<v8::Task>, double, const int&)' marked 'final', but is not virtual
gyp ERR! build error
gyp ERR! command "/usr/local/bin/node" ".../node-gyp.js" "rebuild" "--release" "-j" "max"
gyp ERR! node -v v20.20.2

该版本只提供 ABI 127(Node 22)与 ABI 137(Node 24)的预编译产物,目录结构如下:

isolated-vm/prebuilds/linux-x64/isolated-vm.abi127.glibc.node
isolated-vm/prebuilds/linux-x64/isolated-vm.abi137.musl.node

官方发行件的构建脚本也明确写死基础运行时为 nodejs>=24.18.1。因此生产环境直接上 Node 24,既不触发编译,也不会在运行期报 ABI 不匹配。

💡 技术拓展:isolated-vm 是 Hoppscotch 脚本沙箱的底层依赖,它直接绑定 V8 的 C++ ABI,所以对 Node 大版本极其敏感。同类方案还有 vm2(已停止维护、多次逃逸漏洞)、quickjs-emscripten(WASM 隔离、无 ABI 问题但性能低),Hoppscotch 选 isolated-vm 是为了在进程内拿到接近原生 V8 的隔离与性能。

3.2 数据库选 16

Hoppscotch 通过 Prisma 连接 PostgreSQL,15/16 的 SQL 方言一致;16 在 PGDG 仍在维护窗口内,且本次 22 条迁移全部通过,故选 16。不要用 14 及以下,部分迁移用到了较新的时间戳与时区写法。

3.3 前端不用 Node 常驻进程

前端产物是纯静态文件,但 Hoppscotch 是 Vue Router 的 SPA,直接丢给普通静态服务器会出现「刷新子路由 404」。官方发行件用 Caddy 的 try_files {path} / 兜底,本指南沿用同一思路,用 Caddy 单独托管,避免为一个静态目录再跑一个 Node 进程。

四、安装 Node.js 24 与 pnpm

4.1 下载并解压官方二进制

cd /opt
curl -sL -o node24.tar.gz https://nodejs.org/dist/v24.22.1/node-v24.22.1-linux-x64.tar.gz
tar -xzf node24.tar.gz
cp -r node-v24.22.1-linux-x64/. /usr/local/
rm -rf node24.tar.gz node-v24.22.1-linux-x64

安装到 /usr/local 后 node/npm 直接进 PATH,无需改 profile。验证并启用仓库指定的 pnpm 版本:

node -v
npm -v
corepack enable
corepack prepare pnpm@10.34.5 --activate
pnpm -v

实测回显:

v24.22.1
11.19.1
Preparing pnpm@10.34.5 for immediate activation...
10.34.5

⚠️ 注意:必须用 10.34.5。仓库 package.json 有 "packageManager": "pnpm@10.34.5",且 preinstall 钩子执行 npx only-allow pnpm,用 npm 或 yarn 安装依赖会直接被拒绝。

五、安装 PostgreSQL 16 并初始化数据库

5.1 添加 PGDG 源并安装

Ubuntu 22.04 自带源只有 PostgreSQL 14,装 16 需要 PGDG:

install -d /usr/share/postgresql-common/pgdg
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
  -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc
echo 'deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt jammy-pgdg main' \
  > /etc/apt/sources.list.d/pgdg.list
apt-get update -qq
apt-get install -y postgresql-16

安装末尾会执行 post-bootstrap initialization,本机因 /usr/sbin/policy-rc.d 策略未自动拉起服务,需手工启动:

performing post-bootstrap initialization ... ok
syncing data to disk ... ok
invoke-rc.d: policy-rc.d denied execution of start.

5.2 启动实例并建库建号

pg_ctlcluster 16 main start
systemctl start postgresql
psql --version
su postgres -c "psql -c \"CREATE USER hoppscotch WITH PASSWORD 'q1w2e3r4';\""
su postgres -c "psql -c 'CREATE DATABASE hoppscotch OWNER hoppscotch;'"
su postgres -c 'psql -l' | head -6

实测回显:

CREATE ROLE
CREATE DATABASE
psql (PostgreSQL) 16.15 (Ubuntu 16.15-1.pgdg22.04+2)
                                                     List of databases
    Name    |   Owner    | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules |   Access privileges
------------+------------+----------+-----------------+---------+-------+------------+-----------+-----------------------
 hoppscotch | hoppscotch | UTF8     | libc            | C.UTF-8 | C.UTF-8 |           |           |
 postgres   | postgres   | UTF8     | libc            | C.UTF-8 | C.UTF-8 |           |           |
 template0  | postgres   | UTF8     | libc            | C.UTF-8 | C.UTF-8 |           |           | =c/postgres          +

⚠️ 注意:CREATE DATABASE 必须指定 OWNER hoppscotch。若用 postgres 超级用户建库而属主留空,后续 prisma migrate deploy 会在建表阶段报 permission denied for schema public。

六、获取源码与安装依赖

6.1 下载 2026.9.0 源码包

cd /opt
curl -sL -o hoppscotch-2026.9.0.tar.gz \
  https://codeload.github.com/hoppscotch/hoppscotch/tar.gz/refs/tags/2026.9.0
tar -xzf hoppscotch-2026.9.0.tar.gz
mv hoppscotch-2026.9.0 hoppscotch
rm hoppscotch-2026.9.0.tar.gz
ls /opt/hoppscotch | head -5

实测源码包 9.5 MB,解压后顶层为 monorepo 结构(packages/ 下含 backend、selfhost-web、common 等 12 个包)。

6.2 安装 monorepo 依赖

cd /opt/hoppscotch
export http_proxy=http://192.168.1.62:7897 https_proxy=http://192.168.1.62:7897
pnpm install --prefer-offline

实测耗时与结果:

Progress: resolved 2618, reused 298, downloaded 1336, added 1684
...
Done in 33.5s using pnpm v10.34.5

⚠️ 注意:pnpm 10 默认拦截依赖的构建脚本,本次仅提示 Ignored build scripts: @parcel/watcher@2.6.0, @scarf/scarf@1.4.0, unrs-resolver@1.11.1,三者都只影响开发期文件监听/遥测,不影响后端与前端构建。若后续升级依赖后出现 isolated-vm 编译,说明当前 Node 版本拿不到预编译产物,回到 §3.1 换 Node 24,而不是执行 pnpm approve-builds 硬编译。

七、配置 .env

后端与前端构建共用仓库根目录的 .env(Vite 的 envDir 指向仓库根)。创建 /opt/hoppscotch/.env:

cat > /opt/hoppscotch/.env <<'EOF'
DATABASE_URL=postgresql://hoppscotch:q1w2e3r4@127.0.0.1:5432/hoppscotch?connect_timeout=300
DATA_ENCRYPTION_KEY=hoppscotch2026demoencryptionkey!
PRODUCTION=true
PORT=8121
WHITELISTED_ORIGINS=http://localhost:8122,http://127.0.0.1:8122
TRUST_PROXY=false
PROXY_APP_URL=https://proxy.hoppscotch.io
VITE_BASE_URL=http://localhost:8122
VITE_SHORTCODE_BASE_URL=http://localhost:8122
VITE_ADMIN_URL=http://localhost:8123
VITE_BACKEND_GQL_URL=http://localhost:8121/graphql
VITE_BACKEND_WS_URL=ws://localhost:8121/graphql
VITE_BACKEND_API_URL=http://localhost:8121/v1
VITE_ALLOWED_AUTH_PROVIDERS=EMAIL
EOF

各变量作用与本次取值依据:

变量必填说明
DATABASE_URL是Prisma 连接串;connect_timeout=300 避免慢启动被误判
DATA_ENCRYPTION_KEY是32 字符,用于加密数据库内敏感配置;缺失时启动即抛 ENV_NOT_FOUND_KEY_DATA_ENCRYPTION_KEY
PRODUCTION建议为 true 时启用生产 CORS、关闭 GraphQL Playground
PORT否后端监听端口,缺省 3170,本文显式 8121
WHITELISTED_ORIGINS生产必填允许跨域的前端来源,逗号分隔;生产模式下 main.ts 直接 .split(','),为 undefined 会抛错
TRUST_PROXY否反向代理后置 true,否则限流按代理 IP 计数
VITE_BASE_URL是(前端)构建期烘焙的站点地址,决定邮件链接与 CORS 基准
VITE_BACKEND_GQL_URL / VITE_BACKEND_WS_URL是(前端)页面调用的 GraphQL HTTP/WS 地址
VITE_BACKEND_API_URL是(前端)REST 基地址,页面里所有 /v1/* 都拼在此前缀后
VITE_ALLOWED_AUTH_PROVIDERS否本文仅开邮箱 Magic Link

⚠️ 注意:DATA_ENCRYPTION_KEY 必须恰好 32 字符,且上线后不可更换——infra_config 表中的 SMTP 密码、OAuth secret 等都用它加密,换钥会直接抛 ERR_OSSL_BAD_DECRYPT。本文给的是演示值,生产请用 openssl rand -hex 16 生成的 32 位串并单独备份。

另外,2026.9.0 已经不再从环境变量读取 JWT_SECRET / SESSION_SECRET:首次启动会把随机生成的密钥加密写入数据库 infra_config 表,由 loadInfraConfiguration() 回注进程。这一点与旧教程(要求 .env 里写这两个密钥)完全不同。

八、执行数据库迁移

Prisma 7 的 CLI 需要先按 schema 生成客户端,再应用迁移:

cd /opt/hoppscotch
set -a && . ./.env && set +a
cd packages/hoppscotch-backend
pnpm exec prisma generate
pnpm exec prisma migrate deploy

生成客户端实测回显:

✔ Generated Prisma Client (7.9.1) to ./src/generated/prisma in 208ms

迁移实测回显(节选前 8 条与结尾):

Loaded Prisma config from prisma.config.ts.

Prisma schema loaded from prisma/schema.prisma.
Datasource "db": PostgreSQL database "hoppscotch", schema "public" at "127.0.0.1:5432"

22 migrations found in prisma/migrations

Applying migration `20230406064219_init`
Applying migration `20231106120154_embeds_addition`
Applying migration `20231124104640_infra_config`
Applying migration `20231130082054_collection_headers`
Applying migration `20240226053141_full_text_search_additions`
Applying migration `20240519093155_add_last_logged_on_to_user`
Applying migration `20240520091033_personal_access_tokens`
Applying migration `20240621062554_user_last_active_on`
...
All migrations have been successfully applied.

复核迁移状态与表数量:

set -a && . ../../.env && set +a
pnpm exec prisma migrate status | tail -4
su postgres -c "psql -d hoppscotch -c \"select count(*) from information_schema.tables where table_schema=(select current_schema());\""

实测回显:

22 migrations found in prisma/migrations

Database schema is up to date!
 count
-------
    24
(1 row)

九、构建后端与前端

9.1 后端(NestJS)

cd /opt/hoppscotch/packages/hoppscotch-backend
pnpm run build
ls dist/src/main.js

实测回显:

> hoppscotch-backend@2026.9.0 prebuild /opt/hoppscotch/packages/hoppscotch-backend
> rimraf dist

> hoppscotch-backend@2026.9.0 build /opt/hoppscotch/packages/hoppscotch-backend
> nest build

> hoppscotch-backend@2026.9.0 postbuild /opt/hoppscotch/packages/hoppscotch-backend
> mkdir -p dist/mailer && cp -r src/mailer/templates dist/mailer/templates

⚠️ 注意:仓库 package.json 的 start:prod 写的是 node dist/main,但 nest build 实际产物是 dist/src/main.js(dist/ 下还有 prisma.config.js、mailer/)。直接执行 pnpm start:prod 会报 Cannot find module '/opt/hoppscotch/packages/hoppscotch-backend/dist/main',systemd 必须指向 dist/src/main.js。

9.2 前端(selfhost-web)

cd /opt/hoppscotch/packages/hoppscotch-selfhost-web
pnpm run build

Vite 会输出数千条模块转换日志与外部化告警(fs、crypto 等 Node 内置模块被浏览器端依赖引用),属预期噪音。实测收尾:

✓ 6992 modules transformed.
✓ built in 1m 34s

产物目录 124 MB,index.html 标题为:

<title>Hoppscotch • Open source API development ecosystem</title>

十、systemd 托管后端与前端

10.1 后端单元

cat > /etc/systemd/system/hoppscotch-backend.service <<'EOF'
[Unit]
Description=Hoppscotch Backend (NestJS API)
Documentation=https://docs.hoppscotch.io
After=network-online.target postgresql.service
Wants=network-online.target
Requires=postgresql.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/hoppscotch/packages/hoppscotch-backend
EnvironmentFile=/opt/hoppscotch/.env
ExecStart=/usr/local/bin/node /opt/hoppscotch/packages/hoppscotch-backend/dist/src/main.js
Restart=always
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

EnvironmentFile 必须指向绝对路径,systemd 不会展开 ~;Requires=postgresql.service 保证数据库先于应用启动。

10.2 前端单元与 Caddyfile

前端采用 Caddy 官方二进制(Ubuntu 22.04 的 apt 源里没有 caddy 包,直接 apt-get install caddy 会报 E: Unable to locate package caddy):

curl -sL -o /tmp/caddy.tar.gz \
  https://github.com/caddyserver/caddy/releases/download/v2.11.7/caddy_2.11.7_linux_amd64.tar.gz
tar -xzf /tmp/caddy.tar.gz -C /usr/local/bin caddy
chmod +x /usr/local/bin/caddy
caddy version

实测回显:

v2.11.7 h1:yj0Y4fYZGPkSvibBJ1sTWE33xC0fxztVyXEW5iIdUT4=

配置 SPA 回退:

cat > /opt/hoppscotch/Caddyfile <<'EOF'
{
	admin off
	persist_config off
}

:8122 {
	root * /opt/hoppscotch/packages/hoppscotch-selfhost-web/dist
	try_files {path} /
	file_server
	encode gzip
}
EOF

try_files {path} / 是刷新任意子路由不 404 的关键,等价于 nginx 的 try_files $uri /index.html。

cat > /etc/systemd/system/hoppscotch-web.service <<'EOF'
[Unit]
Description=Hoppscotch Web (static frontend via Caddy)
Documentation=https://docs.hoppscotch.io
After=network-online.target hoppscotch-backend.service
Wants=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/hoppscotch
ExecStart=/usr/local/bin/caddy run --config /opt/hoppscotch/Caddyfile --adapter caddyfile
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

10.3 启动与首启行为

systemctl daemon-reload
systemctl enable --now hoppscotch-backend hoppscotch-web
systemctl status hoppscotch-backend hoppscotch-web --no-pager | grep -E 'Loaded:|Active:|Main PID|Memory'

实测回显:

     Loaded: loaded (/etc/systemd/system/hoppscotch-backend.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2026-10-27 13:57:16 UTC; 47s ago
   Main PID: 9141 (MainThread)
     Memory: 207.2M
     Loaded: loaded (/etc/systemd/system/hoppscotch-web.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2026-10-27 13:55:37 UTC; 2min 26s ago
   Main PID: 8707 (caddy)
     Memory: 60.3M

⚠️ 注意:全新数据库上的第一次启动会自动退出一次,日志形如:

Running in production: true
Port: 8121
Stopping app in 5 seconds...
[Nest] 9123 - ... LOG [NestApplication] Nest application successfully started +9ms
Stopping app now with graceful shutdown...

这是 infra-config/helper.ts 在首次启动写入默认 infra_config 后的主动停机,由 systemd Restart=always 在 5 秒后拉起第二个进程,属正常设计。若手工 node dist/src/main.js 前台运行,会看到进程自己退出,误以为崩溃。

端口监听复核:

ss -lntp | grep -E '8121|8122'

实测回显:

LISTEN 0      4096               *:8122            *:*    users:(("caddy",pid=8707,fd=3))
LISTEN 0      511                *:8121            *:*    users:(("MainThread",pid=9141,fd=24))

十一、验证部署

11.1 后端健康检查

curl -s -i http://127.0.0.1:8121/health | head -1
curl -s http://127.0.0.1:8121/health

实测回显:

HTTP/1.1 200 OK
{"status":"ok","info":{"database":{"status":"up"}},"error":{},"details":{"database":{"status":"up"}}}

⚠️ 注意:健康检查路径是不带版本前缀的 /health。按直觉访问 /v1/health 会得到:

{"message":"Cannot GET /v1/health","error":"Not Found","statusCode":404}

因为 HealthController 只有 @Controller('health'),没有参与 URI 版本化;/v1 前缀只作用于业务控制器。

11.2 GraphQL 可用性

curl -s -X POST http://127.0.0.1:8121/graphql \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ __typename }"}'

实测回显:

{"data":{"__typename":"Query"}}

11.3 前端页面

curl -s -o /dev/null -w 'web=%{http_code}\n' http://127.0.0.1:8122/
curl -s http://127.0.0.1:8122/ | grep -o '<title>[^<]*</title>'

实测回显:

web=200
<title>Hoppscotch • Open source API development ecosystem</title>

浏览器访问 http://<服务器IP>:8122 即可看到 Hoppscotch 主界面;页面的 API 请求会走 .env 中烘焙的 http://localhost:8121,因此换服务器 IP 或域名时必须改 VITE_* 后重新构建前端,只重启服务不生效。

十二、配置说明(生产化)

最小可用部署完成后,上线前还需处理以下几项。

  1. HTTPS 与安全 Cookie:社区版登录凭证走 Cookie,官方建议生产启用 HTTPS。前置 nginx/Caddy 反代 8122,并把 VITE_BASE_URL 改成 https://your.domain 后重建前端;反代后置 TRUST_PROXY=true。
  2. SMTP(登录必需):邮箱 Magic Link 登录依赖邮件通道,.env 里需补充 MAILER_SMTP_URL=smtps://user:pass@smtp.example.com:465 与 MAILER_ADDRESS_FROM=no-reply@example.com(或通过管理台引导页写入数据库 infra_config,后者由 DATA_ENCRYPTION_KEY 加密存储)。未配置 SMTP 时页面能打开,但点击登录会在后端日志报 MAILER_SMTP_URL_UNDEFINED。
  3. 密钥与备份:DATA_ENCRYPTION_KEY 单独保管;备份对象是 PostgreSQL 库(pg_dump -U hoppscotch hoppscotch),node_modules 与 dist 均可重建,不必备份。
  4. 日志:两端都走 journald,journalctl -u hoppscotch-backend -f 可看请求级 morgan 记录(GET /health 200 - 5.008 ms)。
  5. 升级流程:替换源码目录 → pnpm install → pnpm exec prisma migrate deploy → 后端 pnpm run build → 前端 pnpm run build → systemctl restart hoppscotch-backend hoppscotch-web。迁移必须在旧进程停机后执行,避免结构变更与运行期查询交叉。

十三、常见问题

Q1:pnpm install 时报 isolated-vm 编译失败,marked 'final', but is not virtual? Node 版本过低(20.x)。按 §3.1 换 Node 24.22.1,预编译产物 ABI 137 直接可用,无需编译工具链。

Q2:prisma migrate deploy 报 P1001: Can't reach database server at 127.0.0.1:5432? 数据库未启动或 DATABASE_URL 未导出。确认 systemctl is-active postgresql 为 active,并在执行 Prisma 命令前 set -a && . ./.env && set +a。

Q3:迁移时报 permission denied for schema public? 建库时没带 OWNER hoppscotch。ALTER DATABASE hoppscotch OWNER TO hoppscotch; 后重跑;已建表的需 ALTER SCHEMA public OWNER TO hoppscotch;。

Q4:后端启动后自动退出,systemd 反复重启? 首次启动的正常行为(§10.3),观察第二次进程即可。若持续重启,看 journalctl -u hoppscotch-backend -n 50,常见为 DATA_ENCRYPTION_KEY 非 32 字符或 WHITELISTED_ORIGINS 为空导致 .split 抛错。

Q5:pnpm start:prod 报找不到 dist/main? start:prod 脚本与真实产物不一致(§9.1),直接用 node dist/src/main.js。

Q6:访问 /v1/health 返回 404? 路径应为 /health(§11.1),健康检查未纳入版本化。

Q7:刷新前端子路由 404? 静态服务缺少 SPA 回退。确认 Caddyfile 里有 try_files {path} /,或换 nginx 时写 try_files $uri /index.html。

Q8:apt-get install caddy 提示找不到包? Ubuntu 22.04 源不含 caddy,按 §10.2 用官方二进制包安装。

十四、卸载与清理

systemctl disable --now hoppscotch-backend hoppscotch-web
rm -f /etc/systemd/system/hoppscotch-backend.service /etc/systemd/system/hoppscotch-web.service
systemctl daemon-reload
rm -rf /opt/hoppscotch
su postgres -c "dropdb hoppscotch"
su postgres -c "psql -c 'DROP USER hoppscotch;'"
apt-get purge -y postgresql-16
rm -f /usr/local/bin/caddy

若还要回收 Node 运行时,删除 /usr/local/bin/node、/usr/local/bin/npm、/usr/local/lib/node_modules 与 /usr/local/include/node 即可;/root/.cache/node/corepack 下的 pnpm 缓存可一并删除。

十五、参考链接