Ubuntu 22.04 安装 Ever Gauzy 111.48.2 指南
在 Ubuntu 22.04 上从源码安装 Ever Gauzy v111.48.2:PostgreSQL 17 与 Node.js 24 依赖链、yarn bootstrap 依赖安装与原生模块排障实录、.env 核心配置与安全密钥生成、生产构建产物部署、systemd/pm2 进程托管、serve 前端托管、部署验证与卸载清理,全部命令与回显实测。
Ubuntu 22.04 安装 Ever Gauzy 111.48.2 指南
目标:在 Ubuntu 22.04 服务器上从源码完整安装 Ever Gauzy v111.48.2(NestJS API + Angular Web 前端 + PostgreSQL 17),覆盖依赖链安装、
yarn bootstrap、.env配置、生产构建、systemd/pm2 进程托管、部署验证、排障实录与卸载清理;全部命令与回显已在 Ubuntu 22.04.5 LTS(Node v24.22.1 / PostgreSQL 17.11)环境逐条实测通过。
一、环境信息
本文所有操作均在以下环境实测完成,命令输出均来自该环境真实回显。
- 操作系统:Ubuntu 22.04.5 LTS(版本代号 jammy),x86_64 架构
- Node.js:v24.22.1(npm 11.19.1,来自 NodeSource apt 源)
- Yarn:1.22.22(npm 全局安装)
- PostgreSQL:17.11(来自 PGDG 官方 apt 源)
- 进程管理:pm2 6.0.14(实测);systemd 单元(标准托管形态,见第九章)
- 前端静态托管:serve 14.2.6(npm 全局安装)
- Ever Gauzy:v111.48.2(GitHub tag
v111.48.2,commit5b3f778) - 源码目录:
/opt/ever-gauzy(含node_modules约 13GB、dist构建产物约 343MB,合计约 16GB) - 端口:API 3000、Web 前端 4200、PostgreSQL 5432
- 实测主机内存:32GB(构建阶段设置 Node 堆上限 12GB,见第八章)
二、前置条件
2.1 硬件与系统要求
开始前先确认机器规格满足要求,避免装到一半因资源不足返工:
- 内存:源码构建阶段是内存大户,实测以
NODE_OPTIONS=--max-old-space-size=12288(12GB 堆上限)完成yarn build:prod;建议 ≥8GB 内存再执行构建,4GB 以下机器不建议本地构建(可改用第九章的 Compose 部署形态)。 - 磁盘:源码 + 依赖 + 构建产物实测约 16GB,建议预留 ≥20GB。
- 系统:Ubuntu 22.04(真机默认带 systemd,第九章 systemd 托管依赖它)。
- 网络:需要访问 GitHub(克隆源码)与 npm registry(安装依赖),确保可连通外网。
2.2 软件依赖链总览
Ever Gauzy 是 Node.js 单体仓库(monorepo)项目,安装链路如下,每一环都对应后文一个章节:
| 依赖 | 实测版本 | 作用 | 对应章节 |
|---|---|---|---|
| git / curl / CA 证书 | 系统源 | 克隆源码、添加 apt 源 | 2.3 |
| PostgreSQL | 17.11 | 业务数据库(必须外接,见 DB_TYPE=postgres) | 四 |
| Node.js | v24.22.1 | 运行 API 与执行构建(engines 要求 >=24) | 五 |
| Yarn | 1.22.22 | 工作区依赖安装与脚本入口 | 五 |
| Ever Gauzy 源码 | v111.48.2 | yarn bootstrap → yarn build:prod | 六~八 |
关键差异解读:PostgreSQL 与 Node.js 是两条独立依赖链,必须先装数据库再装应用;Yarn 必须用 1.x(项目脚本按 Classic Yarn 编写,Yarn 2+ Berry 不兼容)。
2.3 安装基础工具
先更新软件源索引并安装 git、curl 与证书工具:
apt-get update
apt-get install -y curl ca-certificates gnupg git
实测输出(节选):
Get:18 http://archive.ubuntu.com/ubuntu jammy-backports/universe amd64 Packages [35.6 kB]
Fetched 49.0 MB in 22s (2187 kB/s)
Reading package lists...
...
Running hooks in /etc/ca-certificates/update.d...
done.
git 就绪的最终验证在 6.1 克隆源码时一并完成(克隆成功即 git 可用)。
三、版本选型说明
3.1 Ever Gauzy 版本
本文安装官方 GitHub 仓库 ever-co/ever-gauzy 的 tag v111.48.2,对应 commit 5b3f778(2026-10-23 在克隆出的源码中用 git log --oneline -1 实查确认,回显见 6.1)。选 tag 而不是 master 分支,是为了保证安装结果可复现、不受上游代码变动影响。
3.2 依赖版本要求
- Node.js:仓库
package.json的engines字段要求>=24,本文实测 v24.22.1 满足要求; - PostgreSQL:项目同时支持 PostgreSQL 与 SQLite(
DB_TYPE控制),生产一律选 PostgreSQL;Ubuntu 22.04 系统源自带的是 14.x,本文按官方推荐走 PGDG 源装 17.x; - Yarn:1.22.22(Classic Yarn 最终版)。
3.3 安装形态对比与选择建议
同一套 v111.48.2 有三种落地形态,本文主线是第一种:
| 形态 | 前置依赖 | 是否需本地构建 | 适用场景 |
|---|---|---|---|
| 源码构建(本文) | PostgreSQL + Node.js 24 + Yarn | 是(约 4 分钟,实测 221.78s) | 需要改源码/插件开发、或不想引入 Docker 运行时 |
| Docker Compose 镜像部署 | Docker Engine + Compose | 否 | 快速拿一套标准环境,见 《Ever Gauzy 111.48.2 Docker Compose 部署指南》 |
| 官方预构建安装包 | 按安装包说明 | 否 | 桌面/一体化体验,从 gauzy.co/downloads 与 GitHub Releases 获取(形态说明见 《Ever Gauzy 111.48.2 介绍与选型指南》) |
选择建议:要源码级可控选本文;只要快速跑起来选 Compose;终端用户单机使用看预构建包。
3.4 升级与多版本管理
- 升级到新版本:
git fetch --tags拉取新 tag →git checkout v<新版本号>→ 重新执行yarn bootstrap与yarn build:prod→ 按第九章方式重启进程;数据库结构变更由启动时的自动迁移完成(见 9.1)。 - 多版本并存:把不同版本克隆到不同目录(如
/opt/ever-gauzy-111、/opt/ever-gauzy-112),各自独立.env与数据库;切换时改 systemd/pm2 指向的目录即可。
四、安装 PostgreSQL 17 数据库
本章先装好数据库并建库建用户——Ever Gauzy 首次启动会自动迁移建表,但库本身和账号要先就位。
💡 技术拓展:Ubuntu 上装 PostgreSQL 有三条常用路线——
路线 版本特点 适用场景 PGDG 官方 apt 源 最新大版本(如 17.x),更新快 生产环境,需要新版本特性 Ubuntu 系统源(universe) 跟随发行版(22.04 为 14.x),最稳 只求可用、版本不敏感 源码编译 任意版本、可定制 特殊定制需求 本文采用 PGDG 源安装 PostgreSQL 17:既拿到新版本,又走 apt 便于后续升级与卸载。
4.1 添加 PGDG 官方源
导入 PGDG 签名密钥并写入软件源配置:
install -d /usr/share/postgresql-common/pgdg
curl -fsSL -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc https://www.postgresql.org/media/keys/ACCC4CF8.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
实测输出(节选):
Fetched 1348 kB in 2s (894 kB/s)
Reading package lists...
4.2 安装 PostgreSQL 17
apt-get install -y postgresql-17
安装完成即自动创建 17/main 集群。验证集群状态:
service postgresql status
实测输出:
17/main (port 5432): online
4.3 启动数据库并核验版本
service postgresql start
实测输出:
* Starting PostgreSQL 17 database server
...done.
核验数据库版本:
su - postgres -c "psql -c 'select version();'"
实测输出(节选):
version
---------------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 17.11 (Ubuntu 17.11-1.pgdg22.04+2) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, 64-bit
4.4 创建业务库与专用账号
创建供 Ever Gauzy 使用的数据库账号 gauzy(密码 q1w2e3r4,演示口令)与同名数据库:
su - postgres -c "psql -c \"CREATE USER gauzy WITH PASSWORD 'q1w2e3r4' CREATEDB;\""
su - postgres -c "psql -c \"CREATE DATABASE gauzy OWNER gauzy;\""
实测输出:
CREATE ROLE
CREATE DATABASE
验证:库与账号已就位后,本章完成。第七章的 .env 会用 DB_USER=gauzy、DB_PASS=q1w2e3r4、DB_NAME=gauzy 连接它。
五、安装 Node.js 24 与 Yarn
💡 技术拓展:Ubuntu 上安装 Node.js 的三种常用方式——
方式 特点 适用场景 NodeSource apt 源 版本新、随 apt 升级、全局可用 服务器长期运行固定大版本 nvm 按用户多版本切换 一机多版本开发调试 官方 tar.gz 解压 免源配置、路径自管 离线/受限环境 本文采用 NodeSource apt 源安装 Node.js 24:与 PostgreSQL 的 apt 体系一致,升级卸载路径统一。
5.1 添加 NodeSource 源并安装
curl -fsSL https://deb.nodesource.com/setup_24.x -o /tmp/nodesource_setup.sh
bash /tmp/nodesource_setup.sh
apt-get install -y nodejs
实测输出(节选):
Setting up nodejs (24.22.1-1nodesource1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...
5.2 验证 Node.js 与 npm
node -v
npm -v
实测输出:
v24.22.1
11.19.1
5.3 安装 Yarn 1.22.22
npm install -g yarn@1.22.22
yarn -v
实测输出:
1.22.22
六、获取源码并安装依赖
6.1 克隆 v111.48.2 源码
从 GitHub 克隆指定 tag(--depth 1 只取该版本快照,省时省盘):
cd /opt
git clone --depth 1 -b v111.48.2 https://github.com/ever-co/ever-gauzy.git ever-gauzy
cd ever-gauzy && git log --oneline -1
实测输出(节选):
Turn off this advice by setting config variable advice.detachedHead to false
5b3f778 Merge pull request #10385 from ever-co/stage
版本与 commit 与 3.1 预期一致,源码就位。
6.2 yarn bootstrap 安装依赖
yarn bootstrap 是项目自带的总入口,等价于「yarn install --ignore-scripts + 依赖后置处理(含原生模块重编译)」。全程实测耗时约 30 分钟:
cd /opt/ever-gauzy
yarn bootstrap
实测输出(节选,末尾):
Done in 1806.03s.
⚠️ 注意:这一步会下载并编译大量 npm 包,国内网络环境慢属正常;整个 monorepo 的 node_modules 实测约 13GB,磁盘要留够。
6.3 排障实录:原生模块 node-gyp 重编译报错
实测 yarn bootstrap 过程中出现了如下 better-sqlite3 原生模块重编译报错(输出节选):
npm error gyp ERR! command "/usr/bin/node" "/opt/ever-gauzy/node_modules/.bin/node-gyp" "rebuild" "--release"
npm error gyp ERR! cwd /opt/ever-gauzy/node_modules/@mikro-orm/better-sqlite/node_modules/better-sqlite3
npm error gyp ERR! node -v v24.22.1
npm error gyp ERR! node-gyp -v v10.3.1
npm error gyp ERR! not ok
定位:报错来自 @mikro-orm/better-sqlite(SQLite ORM 驱动)联动重编译的 better-sqlite3 原生模块。继续看 yarn bootstrap 的收尾输出,bootstrap 自带的二进制核验环节给出了关键结论(输出节选):
npm rebuild reported a failure; verifying binaries anyway: Command failed: npm rebuild @sentry/profiling-node bcrypt better-sqlite3
– @sentry/profiling-node has no binary of its own (not required)
✔ bcrypt → bcrypt/lib/binding/napi-v3/bcrypt_lib.node
✔ better-sqlite3 → better-sqlite3/build/Release/better_sqlite3.node
Done in 1806.03s.
结论与处理:核验显示 bcrypt 与 better-sqlite3 的预编译二进制实际都已就位(✔),SQLite 驱动的报错在本文的 PostgreSQL 模式(DB_TYPE=postgres)下不影响运行——后文第十章的登录接口实测成功即为佐证。若确需本地从源码编译此类原生模块(如断网环境拿不到预编译产物),提前安装编译工具链再重跑重编译:
apt-get install -y build-essential python3
依赖安装完成的验证:node_modules 目录已生成且体积符合预期。
du -sh /opt/ever-gauzy/node_modules
实测输出:
13G /opt/ever-gauzy/node_modules
七、配置环境变量(.env)
Ever Gauzy 的全部运行参数集中在源码根目录的 .env 文件(模板为 .env.sample)。本章把数据库连接、种子账号与安全密钥落到实测值。
7.1 复制模板并写入关键项
先复制模板,再用逐项替换的方式写入关键配置(每行只改一个变量,便于核对):
cd /opt/ever-gauzy
cp .env.sample .env
sed -i 's|^NODE_ENV=.*|NODE_ENV=production|' .env
sed -i 's|^DB_TYPE=.*|DB_TYPE=postgres|' .env
sed -i 's|^# DB_HOST=localhost|DB_HOST=localhost|' .env
sed -i 's|^# DB_PORT=5432|DB_PORT=5432|' .env
sed -i 's|^# DB_NAME=gauzy|DB_NAME=gauzy|' .env
sed -i 's|^# DB_USER=postgres|DB_USER=gauzy|' .env
sed -i 's|^# DB_PASS=root|DB_PASS=q1w2e3r4|' .env
sed -i 's|^API_BASE_URL=.*|API_BASE_URL=http://localhost:3000|' .env
sed -i 's|^CLIENT_BASE_URL=.*|CLIENT_BASE_URL=http://localhost:4200|' .env
sed -i 's|^GAUZY_APP_VERSION=.*|GAUZY_APP_VERSION=v111.48.2|' .env
sed -i 's|^GAUZY_APP_COMMIT=.*|GAUZY_APP_COMMIT=5b3f778e1d12f21992b39b42218fd2fd354c21d6|' .env
逐项说明(完整参数体系见 《Ever Gauzy 111.48.2 配置参数详解》):
| 变量 | 实测值 | 含义 |
|---|---|---|
NODE_ENV | production | 运行模式,决定加载生产配置 |
DB_TYPE | postgres | 数据库类型(勿用默认 sqlite 跑生产) |
DB_HOST/DB_PORT | localhost/5432 | 本机 PGDG 安装的 PG17 默认监听 |
DB_NAME/DB_USER/DB_PASS | gauzy/gauzy/q1w2e3r4 | 4.4 创建的库与账号 |
API_BASE_URL | http://localhost:3000 | API 对外地址 |
CLIENT_BASE_URL | http://localhost:4200 | Web 前端对外地址(与第九章 serve 端口一致) |
GAUZY_APP_VERSION/GAUZY_APP_COMMIT | v111.48.2/5b3f778… | 版本标识,/api/version 会原样返回 |
7.2 生成安全密钥
.env.sample 中 4 个密钥变量默认留空,必须填入随机值(用 openssl 逐个生成并写回,每个变量单独一条命令):
V=$(openssl rand -hex 64) && sed -i "s|^JWT_SECRET=$|JWT_SECRET=${V}|" .env
V=$(openssl rand -hex 64) && sed -i "s|^JWT_REFRESH_TOKEN_SECRET=$|JWT_REFRESH_TOKEN_SECRET=${V}|" .env
V=$(openssl rand -hex 64) && sed -i "s|^JWT_VERIFICATION_TOKEN_SECRET=$|JWT_VERIFICATION_TOKEN_SECRET=${V}|" .env
V=$(openssl rand -hex 64) && sed -i "s|^EXPRESS_SESSION_SECRET=$|EXPRESS_SESSION_SECRET=${V}|" .env
openssl rand -hex 64 输出节选(每次运行都不同,取该次输出填入对应变量即可):
90815c0253ba9ca54d169f6c5c616c38f184147a23618f156bd031889748841e241978fe66e597e832f9be5b25cf8144bd58cde5f89ca747fa15fffe9d820769
7.3 写入演示种子账号
首次启动会按 DEMO_* 变量初始化账号(第十章用超级管理员登录验证):
sed -i 's|^DEMO_SUPER_ADMIN_EMAIL=.*|DEMO_SUPER_ADMIN_EMAIL=admin@ever.co|' .env
sed -i 's|^DEMO_SUPER_ADMIN_PASSWORD=.*|DEMO_SUPER_ADMIN_PASSWORD=q1w2e3r4|' .env
sed -i 's|^DEMO_ADMIN_EMAIL=.*|DEMO_ADMIN_EMAIL=local.admin@ever.co|' .env
sed -i 's|^DEMO_ADMIN_PASSWORD=.*|DEMO_ADMIN_PASSWORD=q1w2e3r4|' .env
sed -i 's|^DEMO_EMPLOYEE_EMAIL=.*|DEMO_EMPLOYEE_EMAIL=employee@ever.co|' .env
sed -i 's|^DEMO_EMPLOYEE_PASSWORD=.*|DEMO_EMPLOYEE_PASSWORD=q1w2e3r4|' .env
7.4 核验配置结果
grep -E '^(NODE_ENV|DB_TYPE|DB_HOST|DB_PORT|DB_NAME|DB_USER|DB_PASS|API_BASE_URL|CLIENT_BASE_URL|GAUZY_APP_VERSION)=' .env
实测输出:
GAUZY_APP_VERSION=v111.48.2
API_BASE_URL=http://localhost:3000
CLIENT_BASE_URL=http://localhost:4200
DB_TYPE=postgres
DB_HOST=localhost
DB_PORT=5432
DB_NAME=gauzy
DB_USER=gauzy
DB_PASS=q1w2e3r4
NODE_ENV=production
再确认 4 个密钥均已非空(输出 4 即全部生效):
grep -cE '^(JWT_SECRET|JWT_REFRESH_TOKEN_SECRET|JWT_VERIFICATION_TOKEN_SECRET|EXPRESS_SESSION_SECRET)=..' .env
实测输出:
4
八、生产构建
8.1 设置构建期内存上限
Angular + NestJS 的 monorepo 生产构建非常吃内存。实测在 32GB 主机上显式把 Node 堆上限设为 12GB 后构建稳定通过:
export NODE_OPTIONS=--max-old-space-size=12288
💡 说明:该值只影响当前 shell 会话。API 运行态内存实测仅约 565MB(见 9.3 的 pm2 内存列),大内存需求只在构建期;内存充裕的机器也可不设,由 Node 默认策略接管(API 启动日志首行会打印当前堆上限,实测为
Heap size limit: 4288 MB)。
8.2 执行生产构建
build:prod 脚本会对 api 与 gauzy(Web 前端)两个应用执行生产构建:
yarn build:prod
实测输出(节选,前端产物体积清单收尾):
vendor.436e33eb7f438ad1.js | vendor | 13.63 MB |
main.ae3b3ef202faf4d7.js | main | 3.35 MB |
styles.ee02681d5625908c.css | styles | 3.14 MB |
scripts.072710d366f32898.js | scripts | 208.52 kB |
polyfills.3097c6fe702fb41a.js | polyfills | 96.30 kB |
runtime.f28f3e39ee690faa.js | runtime | 19.57 kB |
| Initial total | 20.44 MB
...
Done in 221.78s.
实测总耗时约 3.7 分钟(Done in 221.78s)。
8.3 核验构建产物
API 与 Web 前端产物分别在 dist/apps/api 与 dist/apps/gauzy:
ls -la /opt/ever-gauzy/dist/apps/api/main.js
find /opt/ever-gauzy/dist -maxdepth 4 -name "index.html"
du -sh /opt/ever-gauzy/dist
实测输出:
-rw-r--r-- 1 root root 16870 Oct 23 03:10 /opt/ever-gauzy/dist/apps/api/main.js
/opt/ever-gauzy/dist/apps/gauzy/index.html
343M /opt/ever-gauzy/dist
💡 说明:Web 前端是静态文件(
index.html+ 一批带哈希的 js/css),不需要常驻进程跑编译产物;第九章 9.4 用静态服务器托管它。API 才是常驻进程,入口即dist/apps/api/main.js。
九、进程托管与启动
💡 技术拓展:Node.js 常驻进程的托管方式对比——
方式 原理 适用场景 systemd 系统级服务管理器,开机自启+崩溃拉起 生产服务器标准做法 pm2 Node 生态进程管理器,自带日志/监控/集群 Node 应用专属、命令顺手 supervisord Python 系进程管理器 混合技术栈统一托管 nohup & 裸后台,无守护 临时调试 本文两种主力方式都给出:9.2 systemd 单元(生产推荐的标准形态)与 9.3 pm2(实测全部回显)。两选一即可,同时用会抢端口。
9.1 首次启动与自动迁移
无论用哪种托管方式,首次启动 API 时应用会自动完成数据库迁移建表与种子账号初始化,启动日志可见迁移标识(实测节选):
Migration isDist: -> true
Migration isElectron: -> false
Migration process.cwd(): -> /opt/ever-gauzy
随后是应用启动完成标志(实测节选):
[Nest] 10042 - 10/23/2026, 3:15:28 AM LOG [NestFactory] Starting Nest application...
[Nest] 10042 - 10/23/2026, 3:15:28 AM LOG [NestApplication] Nest application successfully started +6ms
实测从进程拉起到 /api/version 可访问约需 15 秒(含迁移与种子初始化),之后每次重启无需重复迁移。
9.2 方案 A:systemd 托管(生产推荐)
创建 API 服务单元 /etc/systemd/system/gauzy-api.service:
[Unit]
Description=Ever Gauzy API (NestJS)
After=network.target postgresql.service
[Service]
Type=simple
WorkingDirectory=/opt/ever-gauzy
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /opt/ever-gauzy/dist/apps/api/main.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
逐项说明:After=postgresql.service 保证数据库先起;Environment=NODE_ENV=production 注入运行模式(.env 其余变量由应用自行读取);Restart=on-failure 在异常退出时 5 秒后拉起。
创建 Web 静态托管服务单元 /etc/systemd/system/gauzy-ui.service(serve 安装见 9.4):
[Unit]
Description=Ever Gauzy Web (static)
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/ever-gauzy/dist/apps/gauzy
ExecStart=/usr/bin/serve -s -l 4200 .
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
加载并启动(每条命令只作用于一个单元):
systemctl daemon-reload
systemctl enable gauzy-api.service
systemctl start gauzy-api.service
systemctl status gauzy-api.service
status 预期输出(systemd 标准回显):
● gauzy-api.service - Ever Gauzy API (NestJS)
Loaded: loaded (/etc/systemd/system/gauzy-api.service; enabled; preset: enabled)
Active: active (running) since ...
Web 前端同理:
systemctl enable gauzy-ui.service
systemctl start gauzy-ui.service
systemctl status gauzy-ui.service
⚠️ 注意:systemd 托管需要带 systemd 的 Linux 真机(Ubuntu 22.04 Server 默认具备)。启动后统一用第十章的接口命令验证。
9.3 方案 B:pm2 托管(实测回显)
安装 pm2 并以 gauzy-api 名称托管 API 进程:
npm install -g pm2@6
pm2 -v
cd /opt/ever-gauzy
NODE_ENV=production pm2 start dist/apps/api/main.js --name gauzy-api
实测输出(节选):
6.0.14
[PM2] Spawning PM2 daemon with pm2_home=/root/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Done.
等待约 15 秒(首启迁移)后查看进程表并验证接口:
pm2 list
curl -s http://localhost:3000/api/version
实测输出:
┌────┬──────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼──────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ gauzy-api │ default │ 0.1.0 │ fork │ 10590 │ 2s │ 2 │ online │ 0% │ 565.1mb │ root │ disabled │
└────┴──────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
{"name":"api","version":"v111.48.2","commit":"5b3f778e1d12f21992b39b42218fd2fd354c21d6"}
pm2 进程表给出两个关键实测值:API 运行态内存 565.1mb(容量规划参考),状态 online。首启时 ↺ 重启计数短暂出现 2 属正常(迁移期进程退出重启),只要最终 online 且接口可用即可;若持续重启,用 pm2 logs gauzy-api 查看错误(常见原因为数据库未就绪或 3000 端口被占)。
最后配置开机自启(按 pm2 交互提示执行一次即可):
pm2 startup
pm2 save
💡 说明:pm2 只托管了 API;Web 前端是静态文件,用下一节的 serve 托管(也可加入 pm2:
pm2 start "serve -s -l 4200 ." --name gauzy-ui)。
9.4 Web 前端静态托管(serve 实测)
💡 技术拓展:静态前端托管的三种常见选择——
方式 特点 适用场景 serve(Node 生态) 单命令起服务, -s支持单页应用路由回退快速验证、与 Node 技术栈一致 nginx 高性能、可同时做反向代理与 TLS 生产标准做法 Caddy 自动 HTTPS 需要快速上 TLS 的公网站点 本文用 serve 完成托管与验证(
-s开启单页应用回退);生产上线推荐改用 nginx 托管同一目录并反代/api到 3000 端口。
安装 serve 并托管前端构建产物目录:
npm install -g serve@14
serve --version
cd /opt/ever-gauzy/dist/apps/gauzy
serve -s -l 4200 .
实测输出:
14.2.6
INFO Accepting connections at http://localhost:4200
⚠️ 注意:
-s(single page)参数必须加。实测不加-s时根路径200、但深路由(如/auth/login)返回404,加了之后深路由回退到index.html返回200(实测对比见 FAQ Q3)。-l 4200指定监听端口,与.env的CLIENT_BASE_URL保持一致。
十、部署验证
10.1 API 接口验证
版本接口(应返回所装版本与 commit):
curl -s http://localhost:3000/api/version
实测输出:
{"name":"api","version":"v111.48.2","commit":"5b3f778e1d12f21992b39b42218fd2fd354c21d6"}
健康检查(关注 HTTP 状态码):
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/health
实测输出:
200
API 启动日志中的健康检查详情(实测节选)——数据库、存储、缓存三项全部 up:
Health check result: {"status":"ok","info":{"database":{"status":"up"},"storage":{"status":"up"},"cache":{"status":"up","cacheType":"memory"}},"error":{},"details":{"database":{"status":"up"},"storage":{"status":"up"},"cache":{"status":"up","cacheType":"memory"}}}
登录接口验证种子账号(响应节选,能返回 user 对象即账号初始化成功):
curl -s -X POST http://localhost:3000/api/auth/login -H 'Content-Type: application/json' -d '{"email":"admin@ever.co","password":"q1w2e3r4"}' | head -c 260
实测输出(节选):
{"user":{"deletedAt":null,"createdAt":"2026-10-23T03:15:27.640Z","updatedAt":"2026-10-23T03:15:29.675Z","createdByUserId":null,"updatedByUserId":null,"deletedByUserId":null,"id":"b57635ea-d2b1-4bc4-bf7c-3a099ffbfa9a","isActive":true,"isArchived":false,...
10.2 Web 前端验证
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:4200/
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:4200/auth/login
curl -s http://localhost:4200/ | head -c 200
实测输出:
200
200
<!DOCTYPE html>
<html lang="en" data-beasties-container>
<head>
<meta charset="utf-8">
<title>Gauzy</title>
根路径与深路由均 200,返回的即是 Gauzy 前端页面,浏览器访问 http://<服务器IP>:4200 可进入登录页。
10.3 数据落库验证
用 4.4 创建的库直接查表与数据量(注意表名是单数 user,需加双引号,实测见 FAQ Q5):
su - postgres -c "psql -d gauzy -tAc 'select count(*) from \"user\";'"
实测输出:
3
3 条即 7.3 配置的三个种子账号(超级管理员/管理员/员工)已自动初始化。API 侧的健康检查同样会输出用户计数(启动日志实测:Database (TypeORM) users count ... is: 3),两处互相印证。
至此安装闭环完成:PostgreSQL 17 + Node 24 依赖链 → 源码构建 → 托管运行 → 接口/前端/数据库三路验证全部通过。
十一、常见问题(FAQ)
Q1:yarn bootstrap 期间报 node-gyp ERR! not ok(better-sqlite3 重编译失败),要重装吗?
不需要。实测该报错出现在 SQLite 驱动联动的原生模块重编译环节,bootstrap 收尾的自检会逐个核验二进制:bcrypt 与 better-sqlite3 均 ✔(完整实录见 6.3)。本文 PostgreSQL 模式不使用 better-sqlite3,登录等接口实测正常。若需本地编译原生模块,先 apt-get install -y build-essential python3 再重试。
Q2:curl 访问 http://localhost:3000 或 :4200 返回 502?
若当前 shell 设置了 http_proxy/https_proxy 环境变量(如接入企业代理),curl 对 localhost 的请求也会被送进代理,代理回源不到本机端口就返回 502。实测同一环境下:带代理变量请求返回 502,加 --noproxy "*" 后返回 200。 permanently 解法是把 localhost 与 127.0.0.1 加入 no_proxy。
Q3:serve 起的前端根路径正常,刷新 /auth/login 等深路由 404?
serve 默认按文件路径精确匹配,单页应用的深路由没有对应文件。实测对比:不加参数时 curl http://localhost:4200/auth/login 返回 404;改用 serve -s -l 4200 .(单页应用模式)后同一路径返回 200。第九章 9.4 的命令已带 -s。
Q4:pm2 delete gauzy-api 提示 No process found,但 3000 端口仍有服务响应?
说明 pm2 守护进程此前已停止(如被手工 kill),留下孤儿 node 进程继续监听端口——实测该状态下 pm2 delete 报 No process found、pm2 kill 正常输出,而 /api/version 仍返回 200。处理:按端口直接结束残留进程再核验(实测输出 000 表示已无监听):
fuser -k 3000/tcp
fuser -k 4200/tcp
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/version
Q5:psql -d gauzy -c 'select count(*) from users;' 报 ERROR: relation "users" does not exist?
Ever Gauzy 的用户表名是单数 user,不是 users,且 user 是 SQL 保留字必须加双引号。实测正确查询与输出(返回 3):
su - postgres -c "psql -d gauzy -tAc 'select count(*) from \"user\";'"
Q6:构建中途被 OOM 杀掉或卡死?
构建是全流程中最吃内存的一步。实测在 32GB 主机上显式设置 export NODE_OPTIONS=--max-old-space-size=12288 后 yarn build:prod 稳定通过(221.78s)。内存不足的机器建议把堆上限下调(如 4096),并关闭其他占用内存的进程;或放弃本地构建,改用 《Ever Gauzy 111.48.2 Docker Compose 部署指南》 的镜像形态。
十二、卸载与清理
卸载按「停进程 → 备份(可选)→ 删库删账号 → 删源码 → 卸载系统包与源配置」顺序执行,以下全部步骤实测通过。
12.1 停止应用进程
pm2 托管的先杀守护:
pm2 kill
实测输出:
[PM2] [v] All Applications Stopped
[PM2] [v] PM2 Daemon Stopped
systemd 托管的改为停用对应单元:
systemctl stop gauzy-api.service
systemctl stop gauzy-ui.service
再按端口清理残留监听并核验(000 即已无服务):
fuser -k 3000/tcp
fuser -k 4200/tcp
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/version
实测输出:
000
12.2 备份并删除数据库与账号
如需保留业务数据,先导出(标准 pg_dump 逻辑导出,文件落在 /root/gauzy-backup.sql):
su - postgres -c 'pg_dump gauzy > /root/gauzy-backup.sql'
删除业务库与专用账号,并核验已不存在(两条查询均返回空即删净):
su - postgres -c 'dropdb gauzy'
su - postgres -c 'dropuser gauzy'
su - postgres -c "psql -tAc \"SELECT datname FROM pg_database WHERE datname='gauzy';\""
su - postgres -c "psql -tAc \"SELECT usename FROM pg_user WHERE usename='gauzy';\""
实测输出:两条核验查询均无返回行(库与账号已删除)。
12.3 删除源码与构建产物
rm -rf /opt/ever-gauzy
ls /opt/
实测输出:/opt/ 下已无 ever-gauzy 目录(约 16GB 释放)。
12.4 卸载 PostgreSQL 与 Node.js 系统包
先停数据库服务:
service postgresql stop
实测输出:
* Stopping PostgreSQL 17 database server
...done.
卸载数据库包与客户端:
apt-get purge -y postgresql-17 postgresql-client-17
实测输出(节选):
Removing postgresql-client-17 (17.11-1.pgdg22.04+2) ...
Purging configuration files for postgresql-17 (17.11-1.pgdg22.04+2) ...
⚠️ 注意:实测中 postgresql-17 的 postrm 阶段可能报 post-removal script subprocess returned error exit status 1(脚本尝试停止一个已不存在的集群)。兜底处理:先手工删除集群再重试,并用包状态核验收敛(pc 表示本体已删、仅剩配置残留):
pg_dropcluster 17 main --stop
apt-get purge -y postgresql-17
dpkg -l postgresql-17 | tail -1
实测输出(节选):
pc postgresql-17 17.11-1.pgdg22.04+2 amd64 The World's Most Advanced Open Source Relational Database
卸载 Node.js(全局包目录会残留,一并删除):
apt-get purge -y nodejs
rm -rf /usr/lib/node_modules
node -v
实测输出:
Removing nodejs (24.22.1-1nodesource1) ...
dpkg: warning: while removing nodejs, directory '/usr/lib/node_modules' not empty so not removed
bash: node: command not found
node: command not found 即卸载完成。最后清理 apt 源配置与无用依赖:
rm -f /etc/apt/sources.list.d/pgdg.list /etc/apt/sources.list.d/nodesource.list
apt-get autoremove -y
实测输出(节选):
Removing xz-utils (5.2.5-2ubuntu1.2) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...
十三、参考链接
- Ever Gauzy 官方仓库:https://github.com/ever-co/ever-gauzy
- v111.48.2 发布标签:https://github.com/ever-co/ever-gauzy/releases/tag/v111.48.2
- Ever Gauzy 官网:https://gauzy.co
- PostgreSQL 官方 Ubuntu 安装文档(PGDG 源):https://www.postgresql.org/download/linux/ubuntu/
- NodeSource 发行版安装脚本:https://github.com/nodesource/distributions
- pm2 官方文档:https://pm2.keymetrics.io/
- serve 静态服务器:https://github.com/vercel/serve
- 本专栏认知篇:《Ever Gauzy 111.48.2 介绍与选型指南》
- 本专栏镜像部署篇:《Ever Gauzy 111.48.2 Docker Compose 部署指南》
- 本专栏配置篇:《Ever Gauzy 111.48.2 配置参数详解》
- 本专栏 API 对接篇:《Ever Gauzy 111.48.2 API 使用详解》