在 Linux 服务器上用 Docker 从零部署 Nexent:从环境准备到首次登录验证

本文解决一个问题:拿到一台干净的 Linux 云服务器,如何用 Docker 把开源智能体平台 Nexent 完整部署起来,并确认它真的能用——包括容器状态检查、浏览器访问、超级管理员首次登录、租户初始化以及进入主工作区。

全文命令均基于 Nexent 官方 AtomGit 仓库(https://atomgit.com/ModelEngine/nexent)当前版本实测整理,照着做即可,不依赖任何图形界面。文中也会把我实际踩中的两个高概率坑(镜像标签不存在、外网访问 502)连同排查过程一起写清楚。

一、背景问题:为什么需要这篇文章

Nexent 是一个基于 Harness Engineering 理念打造的零代码智能体自动生成平台:用自然语言描述需求,就能生成可执行的多模态智能体,底层基于 MCP 工具生态,内置模型集成、知识库、记忆与权限体系。官方对私有化部署提供了 Docker 和 Kubernetes 两种方式。

对于个人开发者和小团队,Docker 是最省事的选择。但新手在 Linux 服务器上实操时,通常会卡在这几个地方:

  1. 服务器是干净的,连 Docker 都没装,而且官方一键脚本在国内网络下可能直接被重置;
  2. 国内网络直接拉取 Docker Hub 镜像频繁超时,部署半路失败;
  3. 部署脚本里的镜像标签和仓库里实际存在的标签对不上,导致 not found;
  4. 部署完不知道怎么确认成功,也不知道默认管理员账号是什么;
  5. 服务在本机正常,但外网浏览器访问返回 502 Bad Gateway,不知道是防火墙还是网关问题;
  6. 遇到端口占用、权限不足、Elasticsearch 起不来等报错不会排查。

这篇文章会把这些坑一次性填平。考虑到国内网络环境,全程使用官方提供的中国大陆镜像源(mainland),并对其中标签失效的部分做了显式修正。

二、环境与版本说明

部署前先明确版本,避免“我这边能跑、你那边报错”。以下是本次实测的环境与版本信息:

项目本次实测说明
操作系统Ubuntu 22.04.4 LTS(x86_64),内核 5.15同样适用于 CentOS 7+、Debian 等主流发行版
仓库代码版本v2.8.0(以根目录 VERSION 为准)部署脚本据此自动推导镜像标签
实际运行镜像应用镜像 v2.8.1,data-process 用 latest原因见第 5 节:仓库里没有 v2.8.0 的应用镜像
Docker29.9.3官方要求 24 及以上
Docker Composev5.7.0(docker compose 子命令)不建议再用 v1 的 docker-compose
CPU / 内存12 vCPU / 31 GiB最低 4 核 / 8 GiB,推荐 8 核 / 16 GiB
磁盘97 GB(实测占用约 20 GB)最低 40 GiB,推荐 100 GiB
数据持久化目录默认 ~/nexent-data即 .env 中的 ROOT_DIR,可自行修改

步骤 0:检查服务器资源是否达标

SSH 登录服务器后,先核对配置。我这台机器的初始状态如下(干净系统,Docker 尚未安装):

$ whoami && uname -m
ubuntu
x86_64
$ nproc && lscpu | grep 'Model name'
12
Model name: Intel(R) Xeon(R) Gold 6248R CPU @ 3.00GHz
$ free -h
               total   used   free  ...  available
Mem:            31Gi   205Mi   30Gi ...      30Gi
$ df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        97G  1.6G   96G   2% /
$ sudo -n true && echo "passwordless-sudo-ok"
passwordless-sudo-ok

如果内存不足 8 GiB 或磁盘剩余不足 40 GiB,建议先扩容或更换服务器,否则后面排查问题会非常被动。

三、安装 Docker 与 Compose 插件

首选:官方一键脚本(可能被墙)

官方提供了一键安装脚本,国内通常加 --mirror Aliyun 走阿里云:

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

但我在这台机器上执行时,直连 get.docker.com 直接被重置,无法下载:

curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection to get.docker.com:443

更稳的兜底:用 apt 配置阿里云 docker-ce 源安装

既然一键脚本走不通,就直接用系统包管理器装。Ubuntu/Debian 的完整流程如下(CentOS 把 apt 换成 yum、源换成对应阿里云 docker-ce repo 即可):

# 1) 安装依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release

# 2) 添加 Docker 官方 GPG 密钥(阿里云镜像)
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# 3) 写入 docker-ce apt 源(阿里云)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
$(. /etc/os-release && echo $VERSION_CODENAME) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 4) 安装 Docker 与 Compose 插件
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

安装完成后,启动 Docker 并设置开机自启:

sudo systemctl enable --now docker

验证安装结果,能正常打印版本号即说明成功。我实际装到的版本是:

$ docker --version
Docker version 29.9.3, build 545199
$ docker compose version
Docker Compose version v5.7.0

默认情况下普通用户执行 docker 需要加 sudo。为了后续操作方便,把当前用户加入 docker 用户组(重新登录后生效):

sudo usermod -aG docker $USER
# 重新 SSH 登录,或在当前会话临时生效
newgrp docker

四、下载 Nexent 源码

Nexent 的部署脚本和编排文件都在源码仓库里。直接从官方 AtomGit 仓库克隆:

git clone https://atomgit.com/ModelEngine/nexent.git
cd nexent

进入目录后确认版本号,本次代码版本为 v2.8.0:

$ cat VERSION
v2.8.0

仓库根目录的 deploy.sh 是统一部署入口,它会把命令转发到 deploy/docker/deploy.sh 这个真正的 Docker 部署实现;uninstall.sh 则是对应的卸载入口。

五、关键坑之一:镜像标签不存在(重点)

这是我部署过程中最值得展开的一个问题,因为它不是网络问题,而是脚本默认标签和仓库实际标签对不上。

5.1 先看默认镜像源是怎么写的

选择 mainland 镜像源时,应用镜像的地址来自 deploy/env/image-source.mainland.env,原始内容里应用镜像都用 ${APP_VERSION} 占位:

NEXENT_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent:${APP_VERSION}
NEXENT_WEB_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent-web:${APP_VERSION}
NEXENT_DATA_PROCESS_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent-data-process:${APP_VERSION}
NEXENT_MCP_DOCKER_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent-mcp:${APP_VERSION}
NEXENT_SANDBOX_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent-sandbox:${APP_VERSION}

APP_VERSION 由部署脚本自动读取,最终取到的就是代码版本 v2.8.0。于是脚本去拉 nexent:v2.8.0,结果报错:

failed to resolve reference "ccr.ccs.tencentyun.com/nexent-hub/nexent:v2.8.0":
  ccr.ccs.tencentyun.com/nexent-hub/nexent:v2.8.0: not found
Error response from daemon: No such image:
  ccr.ccs.tencentyun.com/nexent-hub/nexent-data-process:v2.8.0

5.2 先查清楚仓库里到底有哪些标签

不要凭感觉改标签,先把仓库的真实标签列表查出来。腾讯云容器镜像服务支持匿名取 token 后查询:

# 1) 取匿名访问 token
TOKEN=$(curl -s "https://ccr.ccs.tencentyun.com/service/token?service=token-service&scope=repository:nexent-hub/nexent:pull" \
  | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")
# 2) 列出标签
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://ccr.ccs.tencentyun.com/v2/nexent-hub/nexent/tags/list"

把几个应用仓库的 2.8.x 标签单独整理后,结论很清楚:

镜像仓库里实际存在的 2.8.x 标签
nexentv2.8.1、v2.8.2、v2.8.3、v2.8.3.1、v2.8.4(没有 v2.8.0)
nexent-webv2.8.0、v2.8.1、v2.8.2、v2.8.3、v2.8.3.1、v2.8.4
nexent-mcpv2.8.0、v2.8.1、v2.8.2、v2.8.3、v2.8.3.1、v2.8.4
nexent-sandboxv2.8.1、v2.8.2、v2.8.3、v2.8.3.1、v2.8.4(没有 v2.8.0)
nexent-data-process没有任何 2.8.x 标签,最新只到 v2.7.0,另有 latest

也就是说:主镜像 nexent 和 nexent-sandbox 在 2.8 系列里从 v2.8.1 才开始,而 data-process 干脆没有 2.8 版本。继续用 ${APP_VERSION}(v2.8.0)必然失败。

5.3 修正:把占位标签改成确实存在的标签

最稳妥的做法是显式写死标签,不再依赖自动推导。考虑到代码是 v2.8.0,选择与之最接近的 v2.8.1 作为应用镜像;data-process 用维护中的 latest(构建于 2026-09-22,与当前版本时间线一致)。

把 deploy/env/image-source.mainland.env 整体改写为:

NEXENT_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent:v2.8.1
NEXENT_WEB_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent-web:v2.8.1
NEXENT_DATA_PROCESS_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent-data-process:latest
NEXENT_MCP_DOCKER_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent-mcp:v2.8.1
NEXENT_SANDBOX_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent-sandbox:v2.8.1

ELASTICSEARCH_IMAGE=elastic.m.daocloud.io/elasticsearch/elasticsearch:8.17.4
POSTGRESQL_IMAGE=docker.m.daocloud.io/postgres:15-alpine
REDIS_IMAGE=docker.m.daocloud.io/redis:alpine
MINIO_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/minio:RELEASE.2023-12-20T01-00-02Z
OPENSSH_SERVER_IMAGE=ccr.ccs.tencentyun.com/nexent-hub/nexent-ubuntu-terminal:v2.8.1

SUPABASE_KONG=docker.m.daocloud.io/kong:2.8.1
SUPABASE_GOTRUE=docker.m.daocloud.io/supabase/gotrue:v2.170.0
SUPABASE_DB=docker.m.daocloud.io/supabase/postgres:15.8.1.060

小提示:deploy/env/.env 里还有一行硬编码的 NEXENT_MCP_DOCKER_IMAGE=...:v2.8.0,为避免歧义,一并改成 v2.8.1:
sed -i 's#nexent-mcp:v2.8.0#nexent-mcp:v2.8.1#' deploy/env/.env

六、执行 Docker 部署

6.1 交互式部署(适合第一次跑)

在仓库根目录执行,会依次进入组件、端口策略、镜像源、沙箱、数据目录等配置环节:

bash deploy.sh docker

各选项的含义和建议如下:

  • 组件 Components:infrastructure(Elasticsearch、PostgreSQL、Redis、MinIO)为必选;要体验完整功能,把 application、data-process、supabase 全部保持选中。
  • 端口策略 Port Policy:学习排查选 development(各服务端口暴露到主机);正式对外建议 production(只暴露 Web 入口)。
  • 镜像源 Image Source:国内选 mainland(应用走腾讯云、基础镜像走 DaoCloud 加速)。
  • 沙箱模式 Sandbox Mode:默认 lightweight 即可;full 体积更大,disabled 关闭沙箱。
  • 数据目录 ROOT_DIR:默认 $HOME/nexent-data,无特殊需求直接回车。

6.2 非交互部署(本次实际使用,也适合 CI/CD)

不方便交互时,一条命令即可,效果与上面的选择一致。我这次就是用非交互方式跑的:

bash deploy.sh docker --defaults \
  --components infrastructure,application,data-process,supabase \
  --port-policy development \
  --image-source mainland

脚本会自动完成:生成运行配置与各类密钥 → 拉起基础设施 → 启动 Supabase 与核心应用 → 生成 ES API Key → 创建默认超级管理员。确认配置后无需人工干预。

七、结果验证:怎么确认部署真的成功了

“脚本跑完了”不等于“部署成功了”,按下面几个层次逐一验证。

验证 1:容器状态全部正常

$ docker ps --format 'table {{.Names}}\t{{.Status}}'
NAMES                  STATUS
nexent-runtime         Up 23 minutes
nexent-mcp             Up 23 minutes
nexent-northbound      Up 23 minutes
nexent-config          Up 23 minutes
nexent-data-process    Up 23 minutes
nexent-web             Up 23 minutes
supabase-auth-mini     Up 33 minutes (healthy)
supabase-kong-mini     Up 33 minutes (healthy)
supabase-db-mini       Up 34 minutes (healthy)
nexent-postgresql      Up 41 minutes
nexent-redis           Up 41 minutes (healthy)
nexent-elasticsearch   Up 41 minutes (healthy)
nexent-minio           Up 41 minutes

一共 13 个容器全部 Up,其中 Redis、Elasticsearch、Supabase 三个带健康检查的均为 healthy。

验证 2:端口探测与成功标志

$ curl -sI http://localhost:3000 | head -3
HTTP/1.1 307 Temporary Redirect
location: /zh
...
$ curl -sL -o /dev/null -w 'final=%{url_effective} code=%{http_code}\n' http://localhost:3000
final=http://localhost:3000/zh code=200

3000 端口先 307 跳转到 /zh,跟随跳转后返回 200。部署日志末尾出现官方明确的成功标志:

🎉 Deployment completed successfully!
🌐 You can now access the application at http://localhost:3000

八、关键坑之二:外网访问 502 Bad Gateway

8.1 现象:本机能通,外网 502

服务器本机 curl 一切正常,但在自己电脑浏览器访问 http://公网IP:3000 时,返回的是 502 Bad Gateway,而不是连接超时。

这里要先理解一个点:华北二A 的实例虽然有独立公网 IP,但入站 HTTP 流量会经过平台的 Ingress 网关,再由账号级外网防火墙决定是否放行。3000 端口默认不在放行列表里,网关找不到可用的上游,于是返回 502——这跟“端口没开”是同一类问题,只是表现成了 502 而不是连接拒绝。

8.2 处理:在「外网防火墙」放行 3000

在优云智算控制台操作(其他云厂商对应「安全组/防火墙」):

  1. 打开「实例列表」→ 目标实例 →「更多操作」→「配置防火墙」;
    (或进入「GPU 算力服务 → 外网防火墙」,编辑绑定到该实例的防火墙)
  2. 新增一条规则:
    • 协议:TCP
    • 端口:3000
    • 源地址:0.0.0.0/0(想更安全可只填自己的公网 IP)
    • 动作:接受 / 放行
  3. 保存并确认规则已绑定实例。

放行后再访问,返回即变为 HTTP 200,页面标题为 Nexent。

九、浏览器登录与租户初始化

9.1 首次访问与登录弹窗

浏览器打开 http://公网IP:3000,先看到欢迎弹窗,点「登录账户」进入登录界面。

在这里插入图片描述
在这里插入图片描述

默认超级管理员账号(脚本通过 deployment_super_admin_password 生成,默认值定义在 deploy/common/common.sh):

  • 账号:suadmin@nexent.com
  • 密码:Nexent@123

该账号是系统最高权限账户,仅用于平台与租户管理,不能直接开发智能体。建议登录后尽快修改默认密码。

9.2 超级管理员登录后创建租户

用 suadmin 登录后进入[租户资源管理],初始状态下暂无租户。

点左侧租户卡片右上角的+,弹出创建租户对话框,可填租户名称,并选择是否[立即生成租户管理员账户][自动安装官方技能]。

在这里插入图片描述

推荐一次性把租户管理员也建出来:打开[立即生成租户管理员账户]开关,填写管理员邮箱和密码(两次输入需一致)。我这里填的是:租户名 魔擎工作租户、管理员邮箱 admin@moqing.com.
在这里插入图片描述

点确定后,租户和管理员一并创建,用户列表里能看到该管理员,类型为[管理员]、属于 Default Group。

在这里插入图片描述

9.3 切换租户管理员登录,进入主工作区

这里有个权限细节要注意:suadmin 直接访问工作台会提示「无权限访问」,因为它是平台级角色、不属于任何租户。所以需要:

  1. 在用户设置里「退出登录」;
  2. 用刚创建的租户管理员 admin@moqing.com 重新登录;
  3. 此时即可进入主工作区,左侧是完整的功能导航:工作台、智能体对话、自动任务、模型配置、知识库配置、智能体配置、记忆配置、智能体评估、Agent 仓库、MCP 仓库等。

在这里插入图片描述

9.4 关于【暂无可用模型】

刚进工作台时对话区会提示暂【无可用模型】,这不是部署失败,而是还没配置大模型。在【模型配置】页可以看到大语言、向量、图片理解、重排、图片生成、音视频等各类模型当前都是【不使用】,在这里填入对应模型供应商的 API Key 即可启用。

在这里插入图片描述

配置好模型后,就能在工作台对话、创建智能体。Agent 仓库用于浏览同租户共享的智能体(新租户初始为空,属正常现象)。

在这里插入图片描述

成功判据清单(建议逐条打勾):① 13 个容器全部 Up、健康检查 healthy;② 本机 curl 3000 跟随跳转返回 200;③ 外网防火墙放行后浏览器能打开登录页;④ suadmin 能登录并完成租户 + 租户管理员创建;⑤ 租户管理员能登录进入主工作区。

十、常见问题与启动类报错排查

Q1:执行 docker 命令报 permission denied while trying to connect

当前用户还没有 Docker 权限。确认已执行 sudo usermod -aG docker $USER,然后彻底退出并重新 SSH 登录(或 newgrp docker)再重试。

Q2:3000 端口已被占用,脚本启动失败

用 sudo ss -lntp | grep 3000 找到占用进程;要么停掉它,要么编辑 deploy/env/.env 把 NEXENT_WEB_PORT 改成空闲端口(如 3001),重新部署后用新端口访问。

Q3:报 ... : not found / No such image

就是第 5 节的标签问题:默认标签在仓库里不存在。按 5.2 查出真实标签,再按 5.3 改写 image-source.mainland.env,不要反复重试同一个不存在的标签。

Q4:外网浏览器返回 502 或一直转圈

按第 8 节处理:在云平台的外网防火墙/安全组里放行对应端口(Web 为 TCP 3000)。注意区分是平台网关返回的 502(需要放行)还是本机服务没起来(先 docker ps 确认)。

Q5:Elasticsearch 启动失败,日志报 vm.max_map_count ... is too low

宿主机内存映射区域数不足。临时生效:sudo sysctl -w vm.max_map_count=262144;永久生效:

echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

然后重新运行部署。

Q6:某个容器不停重启(Restarting)

先用 docker logs --tail 100 容器名 看真实报错。最常见是内存不足导致 OOM(低于 8 GiB 时高发),其次是数据目录权限问题,按日志针对性处理,而不是反复重启。

Q7:忘记超级管理员密码

需要在 Supabase 与 Nexent 业务库分别清理该账号记录后重新生成,涉及多条 SQL,建议对照官方文档「忘记 suadmin 账号密码」章节逐步执行,不要直接删库。

附:如何干净卸载

在仓库根目录执行:

bash uninstall.sh docker

脚本会交互确认是否删除持久化数据。若要连数据彻底清除(不可恢复),可执行 bash uninstall.sh docker delete-all。

十一、参考链接

  • Nexent 官方 AtomGit 仓库(本文所有操作的代码来源):https://atomgit.com/ModelEngine/nexent
  • Nexent 官方文档首页:https://modelengine-group.github.io/nexent
  • Docker 官方安装文档:https://docs.docker.com/engine/install
  • Nexent 常见问题 FAQ:https://modelengine-group.github.io/nexent/zh/quick-start/faq.html
Logo

更多推荐