Ubuntu 22.04 用 Docker Compose 私有化部署讯飞 Astron Agent 掘金版 📅 发布时间:2026/9/12 4:41:45 👁 浏览次数: 最近老有人问我能不能在自己服务器上跑一个 Agent数据完全不出内网这个问题我上个月帮客户做内部知识库问答机器人时也反复琢磨过。云端的大模型服务和现成的 Agent 平台确实省事可企业内部的产品文档、客户信息、业务流程一旦要过外部接口合规和保密就变成了绕不过去的硬门槛。评估了一圈之后我把讯飞 Astron Agent 掘金版拖下来做了一轮完整的落地测试用 Docker Compose 方式部署到了 Ubuntu 22.04 服务器上。Astron Agent 掘金版简单来说是讯飞给开发者放出来的一个可私有化部署的智能体运行平台底层对话能力基于星火大模型同时支持知识库、插件、任务编排和会话管理。用 Docker Compose 把整套环境拉起来之后所有服务都在你自己的主机上跑业务数据不会离开内网属于完全可控的私有化 Agent 环境。我实际跑了一周从机器选型到 compose 文件编写再到最后用 Python 调通星火 API 做业务验证中间的坑和排错思路全部记录在下面。文章里所有命令和配置都可以直接复制适合自己搭 Agent 平台的开发者、运维以及想在企业内网做 AI 落地的技术负责人参考。1. Astron Agent 掘金版到底是什么为什么值得私有化部署1.1 定位把 Agent 运行环境搬回自己家先说说 Astron Agent 掘金版和普通 API 调用模式的区别。很多人用大模型的方式就是调接口把文本丢给星火或者其他模型服务拿回一段回复就完事。但一个真正能落地的 Agent 不只是能聊天它要能理解任务、拆解步骤、调用外部工具、检索知识库、记住上下文甚至串联起一组自动化业务流程。Astron Agent 做的事情就是把这一整套运行和编排环境打包起来你部署好之后它负责管理 Agent 的生命周期、任务调度、知识库索引、会话记录而不是单纯给你当个模型转发代理。掘金版这个命名容易让人误解成在线商业版的阉割版。从我拿到的版本看它的核心能力和在线版同源区别主要在于授权范围和打包方式。掘金版更适合三类人第一企业内部做 AI 原型的快速验证因为数据不用出网法务和合规基本不会卡你第二独立开发者在自己的服务器上做 Agent 实验自己掌控服务运行状态第三想深度定制界面和流程的团队私有化之后所有配置都在你手里改起来没有平台限制。1.2 部署架构Docker Compose 需要协调哪几个角色在动手写配置之前先要搞清楚整套环境会拉起哪些容器。我自己实际验证下来的容器结构大致如下容器职责定位astron-server主服务负责 Agent 任务接收、编排、状态管理是整套系统的大脑astron-web管理后台和用户界面浏览器里配置 Agent 和知识库入口astron-worker异步任务执行模块处理文档解析、批量检索、模型流式响应等耗时任务astron-redis缓存和消息队列协调 server 和 worker 之间的任务分发astron-postgres元数据和会话记录存储Agent 配置、历史记录、用户信息都在这里除了这几个核心容器如果要用到知识库的向量检索通常还要在数据卷里挂一个向量索引服务比如 pgvector 或者单独部署一套向量数据库这个按需加装。理解了这个架构再看下面 docker-compose.yml 就不会一头雾水也不会出现某个容器挂了不知道该看谁日志的情况。2. 环境准备阶段的三个关键选型2.1 服务器规格怎么定才不浪费第一坑往往不是配置问题而是机器选小了。很多人觉得一个 Agent 平台能有多吃资源拿 2C4G 的机器就想跑。实测下来Astron Agent 的业务逻辑本身不算太吃 CPU但 Docker 环境下同时跑服务端、Web、Redis、PostgreSQL再加上知识库索引进程内存一下子就紧张了。我建议的最低配置是 4 核 CPU、8GB 内存、40GB 可用磁盘如果后续要挂比较大的知识库磁盘至少留 100GB。操作系统方面Ubuntu 22.04 LTS 和 Debian 12 都是实测下来比较稳的老内核系统跑 Docker 经常在容器网络和存储驱动上出兼容问题能用新系统一定换新系统。提示部署前先去服务器上执行free -h和df -h确认内存和磁盘真实余量别只看云厂商控制台上标的数字。2.2 Ubuntu 22.04 安装 Docker 的正确姿势这一步看着基础但坑很多。Ubuntu 22.04 自带 apt 源里的 docker.io 版本比较老Compose 插件版本也跟不上强烈建议用 Docker 官方源安装。我用的命令序列如下sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin装完先别急着部署执行docker compose version看到版本号输出就说明 Compose 插件没问题。这里有个必须说清楚的点新版 Docker 的命令是docker compose空格连接不是老版本的docker-compose中间是横杠。如果你在博客或者教程里看到横杠版本先确认自己的 compose 插件版本否则会一路报command not found。2.3 镜像拉不下来的现实问题怎么解用 Docker 部署最容易遇到的就是镜像拉取速度慢或者直接超时。这个问题有几条常规路径可以处理。第一种是配置 Registry Mirror也就是镜像加速器。在/etc/docker/daemon.json里加registry-mirrors配置然后重启 Dockersudo systemctl restart docker。要注意不同网络环境对不同加速地址的连通性不一样别盲从网上某一条配置自己多试几个地址看哪个实际速度能接受。第二种是分步拉取。别一上来就docker compose up -d那样一旦某个大镜像超时整个组合全部失败排查起来也不知道卡在哪。建议先手动docker pull小的基础镜像确认网络和仓库连通性再拉项目业务镜像。第三种面向内网环境把镜像在能联网的机器上docker pull下来然后docker save打成 tar 包传输到内网服务器后用docker load导入。这个方式在企业内网离线部署时特别实用我这次部分镜像就是用的这个方案稳定可控不用赌外网连接质量。3. 手写 docker-compose.yml 的完整过程3.1 先说整体服务划分不同来源的镜像标签可能不一样这里我提供一个经过验证的配置骨架重点在于讲清楚每个服务的职责和依赖关系照抄时把镜像地址换成你实际使用的版本即可。compose 文件放在项目目录docker-astron/下所有配置我习惯用缩进方式写避免 YAML 解析出错。3.2 核心配置逐段拆解version: 3.8 services: postgres: image: postgres:15-alpine container_name: astron-postgres restart: unless-stopped environment: POSTGRES_USER: astron POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: astron volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: [CMD-SHELL, pg_isready -U astron] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine container_name: astron-redis restart: unless-stopped command: [redis-server, --requirepass, ${REDIS_PASSWORD}, --maxmemory, 512mb, --maxmemory-policy, allkeys-lru, --appendonly, yes] volumes: - redisdata:/data healthcheck: test: [CMD, redis-cli, -a, ${REDIS_PASSWORD}, ping] interval: 10s timeout: 5s retries: 5 server: image: astron-agent/server:latest container_name: astron-server restart: unless-stopped env_file: .env depends_on: postgres: condition: service_healthy redis: condition: service_healthy ports: - 8080:8080 volumes: - ./data:/app/data worker: image: astron-agent/worker:latest container_name: astron-worker restart: unless-stopped env_file: .env depends_on: postgres: condition: service_healthy redis: condition: service_healthy web: image: astron-agent/web:latest container_name: astron-web restart: unless-stopped ports: - 3000:3000 depends_on: - server volumes: pgdata: redisdata:逐个解释几个关键点为什么用restart: unless-stopped而不是always。unless-stopped表示容器异常退出自动重启但如果你手动停了它Docker 不会在开机时强行拉起来。这个语义对运维更友好服务器重启之后服务会自动恢复但管理员手动停掉容器做维护时不会陷入怎么停都停不掉的尴尬。为什么在 Redis 的 command 里直接写密码参数。这里很多人会踩坑以为在environment里配了密码就不会生效。Redis 官方镜像读取密码的方式就是可以在启动命令里加--requirepass也可以挂在配置文件中。直接用 command 参数把${REDIS_PASSWORD}传给 redis-server简单直接还能配合 healthcheck 里的redis-cli -a做健康检查。为什么depends_on要配合condition: service_healthy。这是 compose 服务编排里最容易忽略的逻辑。光写depends_on只能保证容器启动顺序不能保证依赖服务已经就绪比如 PostgreSQL 容器起来了不代表数据库已经接受连接。加上 healthcheck 和condition: service_healthyserver 和 worker 就会等数据库和缓存真正健康后才开始启动第一次跑起来基本不会报数据库连接失败。3.3 环境变量和密钥的安全处理.env文件需要手动创建放在 compose 文件同目录下。内容如下SPARK_APP_ID你的AppID SPARK_API_KEY你的APIKey SPARK_API_SECRET你的APISecret SPARK_API_URLwss://spark-api.xf-yun.com/v3.5/chat SPARK_LLM_DOMAINgeneralv3.5 POSTGRES_PASSWORD请换成强密码 REDIS_PASSWORD请换成强密码 ASTRON_SERVER_PORT8080 ASTRON_WEB_PORT3000.env文件里存的是明文密钥两个安全细节必须做到位第一文件权限改成 600执行chmod 600 .env避免其他系统用户直接读走密钥第二.env绝不能提交到 Git 仓库项目里如果还没有.gitignore赶紧加上一行.env。我看到过很多真实事故就是密钥跟着仓库一起被推到公开代码库后果非常麻烦。env_file: .env和environment:的区别也要搞清楚。environment:是硬编码写进 compose 文件适合放非敏感的固定参数env_file则是把变量从外部文件读进来密钥这种东西放外部.env更灵活还可以在不同环境切换不同的配置不用改 compose 文件本身。4. 从启动到跑通的完整过程4.1 启动前的检查清单配置写完后不要急着 up先把下面几项检查做完能少折腾一小时。端口占用执行ss -lntp | grep -E 8080|3000确认这两个端口没被其他服务占用。如果被占了要么改 compose 里的端口映射要么先停掉占用进程。磁盘空间df -h确认可用空间至少大于 20GBDocker 镜像和数据卷会快速占磁盘。防火墙规则执行sudo ufw status如果开启了防火墙记得放行 3000 和 8080 端口否则浏览器访问不到管理界面。密钥是否填对重新打开.env逐项核对 AppID、APIKey、APISecret 是不是真实有效的不要用占位符。4.2 第一次启动的完整命令流cd docker-astron docker compose config这条命令会把 compose 文件结合.env展开成最终的配置并校验如果有语法错误会在这里直接暴露不用等到容器启动后再排查。配置文件校验通过后再执行docker compose up -d添加-d参数表示后台运行。第一次执行时会拉镜像耗时取决于网络情况可以加个--pull always强制拉取最新镜像。启动完成后用docker compose ps查看容器状态正常情况所有容器应该是Up状态并且有 healthcheck 的容器会显示(healthy)。4.3 健康检查和初始化怎么确认容器起来之后先用docker compose logs -f server观察主服务日志确认没有数据库连接错误和模型 API 鉴权报错。然后浏览器访问http://服务器IP:3000第一次打开会进入管理员初始化页面需要设置管理员账号密码这一步做完之后才能真正创建 Agent。Web 界面能打开只是第一步。我建议在初始化完成后创建一个小测试 Agent不做知识库先发一句你好看它能不能回复。这个测试能快速验证三条链路是否通畅Web 到 server 的连通性、server 到星火大模型的 API 链路、以及整个编排流程是否正常。如果这一步就有问题别急着往下走先看第 5 章的错误排查。5. 部署实测中绕不开的坑5.1 Cannot connect to the Docker daemon完整排查这个报错几乎是所有 Docker 部署新手都会撞上的墙我在部署过程中也遇到过两次。报错信息长这样Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?完整排查链路如下第一步确认 Docker 服务状态。执行systemctl status docker如果显示inactive (dead)说明服务根本没起来。刚安装完 Docker 之后服务一般会自启但有些瘦身系统镜像会关掉自动启动需要手动执行sudo systemctl enable --now docker第二步排查用户权限。如果服务是 active 状态但普通用户执行 docker 命令还是报连接失败那基本是 socket 权限问题。Docker 默认只允许 root 用户和 docker 组的成员访问/var/run/docker.sock。把当前用户加进 docker 组sudo usermod -aG docker $USER注意加完组之后必须重新登录会话光执行命令不重登不会生效很多人卡在这一步。第三步看守护进程日志。如果服务启动失败执行journalctl -u docker -n 50最常见的故障点是 iptables 规则相关报错一般可以通过sudo systemctl restart docker解决如果系统里装了多个容器网络插件可能需要清理残留的网桥或 iptables 规则。5.2 Redis 容器化生产环境配置Redis 这个容器看起来人畜无害但如果你直接docker run redis裸奔上线迟早出事。我在 compose 里专门给它加了几个生产参数原因如下--requirepass是必须的。容器部署的 Redis 默认监听 0.0.0.0在内网环境相当于对局域网所有人开放不设密码等于把缓存数据可能包含会话 token、检索结果挂在门口。--maxmemory 512mb是为了防止内存失控。Redis 容器被打死最常见的场景就是某个任务触发超大检索内存被占满容器直接被内核 OOM kill。--maxmemory-policy allkeys-lru指定内存满了之后按 LRU 策略淘汰冷数据保证服务不会因为缓存膨胀而崩溃。--appendonly yes开启 AOF 持久化数据写到磁盘容器重启后缓存不会全部丢光。5.3 星火 API 超时和鉴权失败的定位我在接入星火大模型时遇到两个典型问题分别是超时和鉴权失败。超时的问题一般只出现在首次请求前端界面发消息后转圈很久才出错。这时候先做连通性测试看服务器能不能访问星火接口域名执行curl -I https://spark-api.xf-yun.com如果请求卡住或者返回连接超时说明服务器和星火接口之间的网络通道有问题。如果内网出口需要走代理务必确认代理配置被正确注入到容器环境变量里否则容器内的请求不会认宿主机的全局代理。鉴权失败报错的代码通常是 404 或者 auth 相关错误。排错顺序是先确认.env里的三把钥匙拼写和值完全正确注意 AppID 和 APIKey 是两回事别填反然后确认SPARK_API_URL是不是对应版本的最新地址星火不同版本v1.1、v2.1、v3.5的接口地址不一样我把 v3.5 的地址写在了示例.env里最后如果你不是用官方 SDK 而是自己拼 WebSocket 请求鉴权 URL 是基于 HMAC-SHA256 动态生成的任何签名参数不一致都会导致 401 或 403这种情况强烈建议直接用官方 SDK别重复造轮子。6. Python 调用星火 API 验证 Agent 效果6.1 获取三把钥匙星火 API 需要三样东西AppID、APIKey、APISecret。登录讯飞开放平台进入控制台创建一个应用就能看到这三样。创建完成后把值填到.env文件里。这里再啰嗦一句三把钥匙是敏感凭证不要贴到代码仓库、别发到聊天群里泄露了立刻去控制台重置。6.2 Python 调用示例Agent 后端调通星火大模型是整套系统正常工作的前提。用官方提供的 Python SDK最简单的调用方式如下from sparkai.llm.llm import ChatSparkLLM from sparkai.core.messages import ChatMessage spark ChatSparkLLM( spark_api_urlwss://spark-api.xf-yun.com/v3.5/chat, spark_app_id你的AppID, spark_api_key你的APIKey, spark_api_secret你的APISecret, spark_llm_domaingeneralv3.5, ) messages [ChatMessage(roleuser, content请用一句话介绍你自己)] resp spark.generate([messages]) print(resp.generations[0].text)依赖安装一般就是pip install sparkai具体包名和类名以官方文档最新版本为准接口签名不同版本可能有细微差异。这个示例的目的是帮你验证鉴权和连通性如果 Python 能正常返回内容说明星火链路通了Astron Agent 收到用户消息后也能正常拿到模型响应。6.3 把 Agent 接入自己的业务Python 验证通过后就要回到 Agent 平台本身去测它的编排能力了。在 Web 管理后台创建一个内部知识库问答Agent上传几个内部文档建索引然后通过 HTTP 接口调用 Astron Agentcurl -X POST http://localhost:8080/api/v1/agent/chat \ -H Content-Type: application/json \ -d {agent_id:你的AgentID,message:公司产品线里退货率最高的是哪一类}这个请求会先触发 Agent 检索知识库再把检索结果和用户问题一起交给星火模型生成回答。如果之前没建知识库模型只能靠自己的训练知识回答建了知识库之后回答会明显带上文档里的具体内容那才是 Agent 真正在业务流程里起作用的状态。7. 跑起来之后的维护建议7.1 日志和磁盘占用控制Docker 默认的日志驱动不限制文件大小每个容器的 JSON 日志会无上限增长。我见过有人部署了一个容器三个月后/var/lib/docker/containers下日志文件占了几十个 GB直接把磁盘写满。要提前用日志限制配置在/etc/docker/daemon.json里加上{ log-driver: json-file, log-opts: { max-size: 20m, max-file: 3 } }改完执行sudo systemctl restart docker。注意这个配置只对新创建容器生效已存在的容器需要用docker compose up -d --force-recreate重建后才生效。7.2 数据备份和恢复Astron Agent 最重要的数据源是 PostgreSQL 和 Redis 两个数据卷。备份 PostgreSQL 数据卷可以用如下命令docker run --rm -v astron_pgdata:/data -v $(pwd):/backup alpine tar czf /backup/pgdata.tar.gz -C /data .这条命令的意思是用 alpine 容器挂载两个目录一个是 PostgreSQL 的数据卷一个是当前目录然后把数据卷打成压缩包备份到当前目录。恢复就反过来解包docker run --rm -v astron_pgdata:/data -v $(pwd):/backup alpine tar xzf /backup/pgdata.tar.gz -C /data建议用 cron 定期执行备份任务比如每天凌晨两点把 pgdata 和 redisdata 都打一份包保留最近 7 天成本低真出问题的时候能救命。7.3 版本升级注意事项升级流程我建议严格按下面这个顺序走先备份数据和配置文件再执行docker compose pull拉取新镜像然后docker compose up -d重建变化的容器最后观察日志和回归测试。千万别跳步骤。特别是数据库结构变更的版本官方升级说明里通常会标注先备份再迁移这句话不是客套话我见过太多人因为跳过了备份升级到一半数据结构不兼容只能回滚到旧版镜像重新折腾。升级后至少验证三件事Web 界面能正常打开、已有 Agent 能被正常创建和查询、星火 API 链路能返回新消息。这三条过了基本就可以放心使用了。注意我的升级顺序是先 pull 表现有服务通过docker compose up只重建镜像发生变化的服务而不是先手动docker stop全部容器再启动那样会无端扩大故障窗口。跑了一周之后我最直观的体会是私有化部署的价值不在于把服务装进去这个动作本身而在于后续的数据归属、流程编排、权限控制全都握在自己手里。我也建议第一次部署的人别追求一次成功把docker compose logs当成日常排错的入口每做一步都记录下当时的环境和结果。这个项目其实还留了不少可玩的空间比如把知识库换成更专业的企业文档管理工具或者对接内部统一登录协议如果你也正在部署 Astron Agent欢迎在实际落地后多交流部署细节和踩坑经验。