Docker Compose实战:私有化部署Astron Agent平台完整指南
2026/9/16 1:18:11 网站建设 项目流程

1. 先搞清楚 Astron Agent 掘金版是什么

我折腾这个项目之前,其实已经见过不少 Agent 平台了,但讯飞 Astron Agent 掘金版给我的第一感觉是:它把“私有化”这件事真正当成一个正经功能在做了,而不是像有些开源项目那样,把私有化部署放在 README 的最后一段,扔几个命令就完事。

Astron Agent 掘金版本质上是一套低门槛的智能体开发与运行平台。你可以把它理解成“一个自带界面的 Agent 编排系统”:通过它创建带工具调用、知识库检索、多轮对话记忆能力的 Agent,然后以 API 或 Web 应用的形式集成到自己的业务系统里。掘金版是面向开发者社区的免费版本,和商业版相比主要差异在并发额度、高级插件和官方技术支持上,但核心的 Agent 编排、星火模型接入、知识库问答这些能力都是完整的。

为什么要做私有化部署?最直接的原因就是数据边界。用在线版虽然方便,但你的业务日志、用户对话、知识库文档都经过了第三方平台,这在很多企业内部是过不了合规审核的。内网部署之后,所有数据都留在自己的服务器上,模型调用走你自有的星火 API 通道,权限和审计都可以自己控制,这才是“掘金版”这类版本对开发者最大的价值。

同时这也是一个很适合用来练手 Docker Compose 编排能力的项目。整个平台不是一个单体程序,而是由后端服务、前端静态资源、数据库、缓存等多个组件组成的,正好适合用容器方式统一管理。如果你之前只在 Docker 里跑过一两个简单容器,这次部署完整个 Compose 栈,对容器网络、健康检查、持久化卷这些概念的理解会深一个台阶。

这篇教程就按我自己实际部署的路径来写:从服务器准备、Docker 环境搭建、Compose 文件编写,到启动验证和问题排查,全程都有实际操作记录,复制命令就能跑。

2. 为什么推荐用 Docker Compose 做私有化部署

2.1 私有化部署的几种常见路线

部署一套 Agent 平台,通常有三条路线可以走。

第一条是裸机部署,也就是直接在服务器上安装 Python、Node.js、PostgreSQL、Redis,然后手动拉代码、建虚拟环境、配 systemd 服务。这种方式的优点是性能损耗最小、调试直观,但缺点是环境依赖极难复现。我之前部署过类似项目,半年后想迁移服务器,光是重新装一遍原生依赖就花了整整一天,更别提你还得记得当时改了哪些配置文件。

第二条是 Kubernetes 部署。K8s 对资源调度、弹性伸缩、滚动更新确实强大,但对一个几台服务器规模的小团队来说,学习成本和运维成本都太夸张了。为了一个 Agent 平台先搭一套 K8s 集群,等于杀鸡用了牛刀。

第三条就是 Docker Compose 了。它把“用代码描述环境”这件事做到了刚刚好的复杂度:编写一个 YAML 文件,声明哪些容器需要启动、它们之间的依赖关系、端口怎么映射、数据往哪里持久化,然后一条 docker compose up -d 就能全部拉起。对于 Astron Agent 掘金版这种服务数量在个位数的项目来说,Compose 是最匹配的运维单元。

我自己选 Compose 还有一个很现实的原因:可迁移性和团队协作。整个部署配置就是项目里的一个目录,包含 docker-compose.yml、.env、nginx 配置和初始化脚本,用 Git 管理起来非常方便。换一台服务器部署,只需要把目录复制过去再执行启动命令,环境一致性完全由镜像和 Compose 文件保证,不会出现“在我机器上能跑”的尴尬。

2.2 Docker Compose 相比单容器 Docker 的关键优势

如果你之前只用过 docker run 启动单容器,你会发现 Compose 带来的不是一点点便利。

最大区别在于网络编排。Compose 会自动创建一个默认网络,所有服务之间可以通过服务名互相访问。在 Astron 的架构里,后端服务需要连接 PostgreSQL 和 Redis,如果手动 docker run,你需要先创建自定义网络,再在每次 run 的时候指定 --network 参数,还要处理容器启动顺序,非常容易出错。Compose 里只需要一个 depends_on 声明,再加上一个简单的健康检查,就能保证数据库先就绪、后端再启动。

另一个优势是配置管理。所有环境变量集中写在 .env 文件里,Compose 文件里用 ${VARIABLE} 引用,既避免了把账号密码硬编码进配置文件,又方便在不同环境之间切换。配合 Compose 的 environment 和 volumes 配置,一次定义、随处运行,这对后续的版本升级和服务器迁移帮助非常大。

注意:如果你以前用过 docker-compose(带横杠的命令),注意现在 Docker 官方推荐的是新版 docker compose 插件命令。下面安装步骤我会把两种情况都覆盖到。

3. 部署前的环境准备

3.1 服务器硬性指标评估

先别急着敲命令,花两分钟确认一下你的服务器配置。我这次部署用的是 4 核 8G 的云主机,实际运行下来,整个 Agent 平台占用的情况是:后端服务常驻内存约 1.5G 左右,PostgreSQL 和 Redis 加起来约 700M,前端 Nginx 几乎可以忽略不计。如果你还要在同一个平台上跑多个 Agent 实例,内存建议直接上到 16G。

磁盘方面,镜像本身加上容器运行数据,预留 20G 是比较舒适的。需要特别留意的数据库和上传文件的持久化路径。我见过有人把数据卷挂到系统盘上,结果系统盘满了把整个服务器搞挂。数据目录单独挂载到数据盘是基本操作。

操作系统我建议直接用 Ubuntu 22.04 LTS 或 Debian 12。这两个系统的内核版本较新,对 Docker 的支持最省心。CentOS 7 虽然还能用,但系统自带的旧内核在跑新版本容器时容易出网络兼容性问题,我没少在这个上面踩坑。下面命令也以 Ubuntu/Debian 系为准。

3.2 安装 Docker 引擎

安装 Docker 没什么玄学,用官方源一次性装好。这里有一个经验:不要用操作系统自带的 docker.io 包,版本太旧了,很多新特性不支持,后续跑 Compose 会遇到莫名其妙的坑。

# 更新 apt 索引并安装依赖 sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release # 添加 Docker 官方 GPG 密钥和软件源 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 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 # 安装 Docker 引擎 sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

注意看最后一行,docker-compose-plugin 就是新版 Compose 插件,装完可以直接用 docker compose 命令。装完执行 docker --version 和 docker compose version 确认一下。这里多说一句:如果服务器在国内,访问 Docker 官方源或镜像仓库都可能比较慢,甚至出现拉取镜像超时。解决办法是配置国内的镜像加速器,这个我在后面搭建镜像配置部分会详细讲一个我自己验证过的方式。

装完之后还有个常规操作:把当前用户加入 docker 组,避免每次执行 docker 命令都要加 sudo。这个步骤不是必须的,但如果你不想整天被 sudo 烦,建议配合执行。

sudo usermod -aG docker $USER newgrp docker

3.3 目录规划与项目初始化

部署之前先把目录结构规划好。我的习惯是统一的 /opt/apps 目录下面放所有自建应用,每个应用独立文件夹,不把配置散落在用户目录里。Astron Agent 掘金版的部署目录我放在 /opt/apps/astron,结构如下:

/opt/apps/astron/ ├── docker-compose.yml ├── .env ├── nginx/ │ └── conf.d/ │ └── default.conf └── data/ ├── postgres/ ├── redis/ ├── uploads/ └── logs/

data 目录下按服务类型分子目录,持久化卷分别挂到对应容器里。这样做的好处是备份和清理都非常清晰:要备份就打包 data 目录,要清理就删对应子目录,不会误伤其他数据。

创建目录的命令很简单:

mkdir -p /opt/apps/astron/{nginx/conf.d,data/{postgres,redis,uploads,logs}}

4. Docker Compose 编排文件详解

4.1 docker-compose.yml 整体结构

到了整个教程最核心的部分了。Astron Agent 掘金版的完整 Compose 编排涉及 4 个服务:PostgreSQL 负责存储用户和会话数据,Redis 承担缓存和异步任务队列,后端服务是 Agent 的运行引擎,Nginx 负责托管前端页面并把 API 请求反向代理到后端。下面是我的 docker-compose.yml 完整内容,每个服务下面我都会单独拆解:

version: "3.8" services: postgres: image: postgres:14-alpine container_name: astron-postgres restart: always environment: POSTGRES_USER: astron POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_DB: astron volumes: - ./data/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U astron -d astron"] interval: 10s timeout: 5s retries: 5 networks: - astron-net redis: image: redis:7-alpine container_name: astron-redis restart: always command: ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD}"] volumes: - ./data/redis:/data healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 5 networks: - astron-net backend: image: astron-agent-server:standalone container_name: astron-backend restart: always depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: DATABASE_URL: postgresql://astron:${DB_PASSWORD}@postgres:5432/astron REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0 SPARK_APP_ID: ${SPARK_APP_ID} SPARK_API_KEY: ${SPARK_API_KEY} SPARK_API_SECRET: ${SPARK_API_SECRET} UPLOAD_DIR: /app/uploads LOG_LEVEL: INFO volumes: - ./data/uploads:/app/uploads - ./data/logs:/app/logs ports: - "8000:8000" networks: - astron-net web: image: nginx:alpine container_name: astron-web restart: always depends_on: - backend ports: - "8080:80" volumes: - ./nginx/conf.d:/etc/nginx/conf.d:ro networks: - astron-net networks: astron-net: driver: bridge

4.2 数据库和缓存服务的编排要点

先看 postgres 服务。我使用 postgres:14-alpine 而非最新的 16,是因为很多 Agent 平台在 14 版本上验证最充分,兼容性问题最少。Alpine 版本镜像体积只有标准版的一半还多,内存占用也更低,适合服务器资源紧张的情况。Volume 挂载了 ./data/postgres 目录,这是最关键的一步:PostgreSQL 的官方镜像要求数据目录必须挂载到 /var/lib/postgresql/data,如果不挂载,容器一重启数据就全没了。

Redis 服务使用了 requirepass 开启密码保护。很多人部署 Redis 时图省事不设密码,这在内网环境可能还能侥幸,但一旦服务器有公网 IP,Redis 就极度容易被扫描入侵,轻则被写入恶意数据,重则被拿去挖矿。这里设置了一段简单的启动命令,同时开启了 AOF 持久化(--appendonly yes),保证 Redis 重启后缓存和异步任务不丢失。

healthcheck 节点值得单独说一下。早期写 Compose 文件的人往往只写 depends_on: - postgres,但 depends_on 只保证容器启动了,不保证数据库已经能接受连接。如果后端容器启动得比 PostgreSQL 的初始化过程快,后端程序连数据库会报 "connection refused",然后整个容器反复崩溃重启。加入健康检查后,depends_on 里要用 condition: service_healthy 来声明依赖——只有 postgres 和 redis 通过健康检查了,后端才会启动。这个写法在部署 Dify、RAGFlow 这类多服务项目时都是通用的,学会一次受益终身。

4.3 后端服务与前端 Nginx 的关键配置

backend 服务是整个平台的大脑。它需要连接数据库和 Redis,还需要访问讯飞星火大模型的 API 凭证。这些敏感信息不要直接写在 Compose 文件里,而是通过 ${SPARK_APP_ID} 这样的变量引用 .env 文件中的值。镜像我写成 astron-agent-server:standalone,实际使用中请去官方仓库拉取对应版本的最新镜像,因为不同版本的镜像名和标签规则可能会有差异。

后端服务的 UPLOAD_DIR 和 LOG_LEVEL 两个环境变量容易被忽略。UPLOAD_DIR 指定了上传文件的存储目录,如果不显式指定,文件可能会存到容器可写层里,容器一旦重建就丢失。LOG_LEVEL 建议在生产环境设为 INFO,调试时再切到 DEBUG,否则日志量会让排查问题变得很痛苦。

web 服务用的是 Nginx,它承担两个任务:托管前端静态页面,以及将 /api 路径的请求反向代理给 backend 服务。我这里把主机 8080 端口映射到容器 80 端口,是为了避免和服务器上可能已经在 80 端口运行的其他服务冲突。如果你确认 80 端口空闲,直接映射 80:80 会让访问地址干净很多。

Nginx 的反向代理配置我放在 ./nginx/conf.d/default.conf:

server { listen 80; server_name _; root /usr/share/nginx/html; index index.html; location /api/ { proxy_pass http://backend:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location / { try_files $uri $uri/ /index.html; } }

注意 proxy_pass 的目标地址写的是 http://backend:8000,这个 backend 就是 Compose 网络里后端服务的服务名。容器之间通过服务名通信,这是 Compose 网络的核心机制,也是正确工作的前提。

4.4 环境变量文件与安全习惯

.env 文件是整个部署的密钥库。内容如下:

# 数据库密码,务必修改为强密码 DB_PASSWORD=astron_secure_db_pwd_2024 # Redis 密码 REDIS_PASSWORD=astron_secure_redis_pwd_2024 # 讯飞星火开放平台凭证 SPARK_APP_ID=your_spark_app_id SPARK_API_KEY=your_spark_api_key SPARK_API_SECRET=your_spark_api_secret

关于星火 API 凭证的获取,我在后面的使用环节会再单独展开。这里要强调一个安全习惯:.env 文件包含了所有密码和 API 密钥,绝不能提交到 Git 仓库。如果团队协作,可以将 .env.example 作为模板提交,真实凭据只在服务器上维护。权限方面也要收紧,执行 chmod 600 .env 让只有当前用户能读。

5. 私有化部署实操全程记录

5.1 拉取镜像的加速配置

部署环境准备好、Compose 文件也已经编写完成后,接下来开始正式启动。如果服务器的 Docker 镜像仓库访问不稳定,建议先在 /etc/docker/daemon.json 里配置镜像加速。这是我实测下来比较顺手的配置:

{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker.1panel.live" ] }

修改后执行 sudo systemctl restart docker 重启 Docker 使配置生效。这里提醒一句:镜像加速只对从 Docker Hub 拉取公共镜像生效,如果你在 Compose 中使用了其他私有仓库的镜像,需要确保对应仓库的网络可达性。

5.2 启动服务与逐项验证

进入部署目录后,第一件事是检查 .env 文件是否已经配置完整。缺了数据库密码或者星火密钥,后端容器即使启动成功也会在运行时报错。检查完之后,先执行 docker compose config 校验 Compose 文件的语法和变量引用是否正确。这个命令会输出解析后的完整配置,其中 ${DB_PASSWORD} 等变量会被替换成实际值,正好可以用来确认密钥有没有被正确读取。

确认配置无误后正式启动:

cd /opt/apps/astron docker compose up -d

第一次启动需要拉取四个镜像,耗时取决于网络状况。拉取完成后,docker compose ps 应该能看到所有服务处于 Up 状态。用 docker compose ps 输出的内容里,需要注意 STATUS 列是否显示 healthy,特别是 postgres 和 redis 两个服务。如果显示 starting 或者 unhealthy,说明健康检查还没通过,这时先不要往下进行,用 docker compose logs 查看具体原因。

验证服务是否真正可用,我用的是下面这组命令:

# 查看后端健康检查接口 curl http://localhost:8000/api/health # 查看前端页面是否可访问 curl -I http://localhost:8080

后端健康接口正常会返回 JSON 格式的状态信息,Nginx 对前端访问会返回 200。如果你的服务器有公网 IP 并且安全组规则放行了 8080 端口,直接用浏览器访问 http://服务器IP:8080 就能看到 Astron Agent 的管理界面。

5.3 创建第一个 Agent 并接入星火模型

平台启动之后,登录管理后台第一件事是配置模型。Astron Agent 掘金版默认支持接入讯飞星火大模型,需要在后台的模型配置页面填入 Spark 的 App ID、API Key 和 API Secret 三个凭证。

在讯飞开放平台创建应用后,这三个凭证在应用详情页可以看到。填入并保存后,建议先在后台的模型自测对话框里发一条消息,确认星火能正常响应。这里有个容易踩坑的地方:星火开放平台的 API 版本有多个,不同版本对应的接口地址不同。如果配置后调用报错,优先检查平台的模型版本和调用地址是否匹配。Astron 的默认配置通常匹配最新版本的星火接口,如果你使用的是旧版本凭证,要及时更新。

模型验证通过之后,创建一个简单的 Agent 试试完整流程。创建时可以给 Agent 加上一个知识库知识源,把团队内部文档上传上去,这样后续使用时就能基于你自己的文档来回答。这一步跑通了,说明整套系统的核心链路都正常,私有化部署就算成功了。

6. 部署过程中最容易踩的坑

6.1 常见问题速查表

我把部署过程中遇到的高频问题整理成一个表格,方便你快速定位。

现象可能原因解决办法
docker compose 命令找不到安装的是旧版 docker-compose用 docker-compose 命令,或安装 compose 插件
postgres 容器一直 unhealthy数据目录权限不对或已有损坏数据检查 ./data/postgres 属主是否为 999 或修改为 0700
后端容器频繁重启depends_on 没写 healthcheck 条件,启动顺序错乱按 4.2 节配置 condition: service_healthy
前端能打开但接口 502Nginx 反向代理配置错误或后端未启动检查 proxy_pass 地址和后端容器状态
上传文件丢失没挂载 UPLOAD_DIR 持久化卷在 volumes 中挂载 ./data/uploads
星火模型调用报鉴权失败API 凭证填错或模型版本不匹配核对 Spark 凭证,确认模型接口版本
服务器重启后服务起不来容器 restart 策略未设置给服务加 restart: always
8080 端口无法访问云安全组未放行在云控制台安全组中开放对应端口

6.2 两个让我印象深刻的排查实录

第一个是 PostgreSQL 容器一直 unhealthy。现象是 postgres 容器状态反复从 starting 变成 unhealthy,日志里报 "FATAL: data directory ... has invalid permissions"。这个问题本质上是因为服务器的 umask 设置导致挂载目录权限不正确,PostgreSQL 进程无法写数据目录。我一开始以为是账号问题,删掉卷重建了好几次都没解决,最后发现只要给宿主机目录设置 0700 权限就能解决。这个坑在官方镜像文档里有详细说明,但新手根本不会主动去翻,我这里帮你踩过了。

第二个是 Nginx 反代出现 502 Bad Gateway。前端页面能正常打开,但调用后端接口时全部失败。排查时我先 docker compose logs backend 确认后端服务本身是正常的,然后用 docker exec -it astron-web sh 进入 Nginx 容器,在里面执行 wget http://backend:8000/api/health,发现容器内无法解析 backend 这个服务名。最终定位原因是 Compose 的默认网络被手动覆盖了:我在启动时通过 docker network connect 把某个旧容器连到了 astron-net 上,导致网络配置错乱。解决办法是删除自建的旧网络,重新 docker compose down 再 up,一切恢复正常。

这两个问题共同启发了一个习惯:遇到诡异问题时,先 docker compose logs 看日志,再 docker compose ps 看状态,最后进入容器内部用 curl 或 ping 测试网络连通性。按这个顺序排查,绝大多数问题都能在十分钟内定位。

7. 上线后的调优与日常维护心得

部署完成不等于事情结束,真正考验人的是后续的日常维护。核心是数据的备份策略。对我影响最大的是把整个 data 目录加入定时备份,用 crontab 每天凌晨执行一次:

0 2 * * * tar -czf /backup/astron_$(date +\%Y\%m\%d).tar.gz -C /opt/apps/astron data .env nginx

备份脚本只打包 data、.env 和 nginx 目录,镜像和容器本身不需要备份,出问题随时可以重新拉取。这个举动的价值在第一次服务器故障时会体现得特别明显。

日志清理也是一个容易被忽视的事项。后端容器在长时间运行后日志文件会越来越大,直到占满磁盘。用一条简单的命令定期清理旧的容器日志文件即可。Docker 自带的 json-file 日志驱动支持按大小轮转,在 docker-compose.yml 里给每个服务加上 logging 配置是更优雅的方案:

logging: driver: "json-file" options: max-size: "50m" max-file: "3"

这样单个容器日志最大 150M 封顶,不会再出现日志把磁盘写满的尴尬。

最后说一点关于升级的经验。升级版本时不要直接 docker compose pull 然后 up -d,而是先备份 data 目录,再执行 docker compose pull 拉取新镜像,接着 docker compose up -d 让 Compose 自动重建有变化的服务。启动后用之前提到的健康检查命令确认所有服务正常,观察一段时间再清理旧镜像。这套流程我从部署 Astron 到现在一直用着,中途升级过两次,都没出过问题。

回到最开始的话题。私有化部署这件事,表面上是把一套服务装到自己的服务器上,本质上是在为自己的数据和业务边界负责。Astron Agent 掘金版用 Docker Compose 部署,是我目前接触到的组合里最平衡的方案——部署门槛不高,可维护性足够,还能顺手把 Docker 编排这套技能练扎实。如果这套流程你已经跑通了,下一步可以尝试把 Composer 文件扩展成多个后端副本再加一层负载均衡,那又是新的一课了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询