avatar

一条在知识海洋的咸鱼

这个家伙很懒,啥也没有留下😋

  • Linux
  • OCJP
  • Java核心技术卷
  • J2EE相关标准
  • 深入理解Java虚拟机
  • NIO与SOcket编程技术指南
  • Java多线程编程核心技术
  • Redis开发与运维
  • Spring Cloud Alibaba 微服务原理与实践
  • DevOps
  • Docker
  • MySQL必知必会
  • AI自学路线
  • Spring Boot 编程思想(核心篇)
  • 首页
主页 36 Docker 化:打包 RAG 应用与基础设施
文章

36 Docker 化:打包 RAG 应用与基础设施

发表于 最近 更新于 最近
作者 Administrator
16~21 分钟 阅读

Docker 化:打包 RAG 应用与基础设施

Docker 化不是为了显得项目专业,而是为了让项目离开自己电脑后仍然能启动、迁移、排错和演示。

[TOC]

1. 这一节到底解决什么问题

前面我们已经把文档上传、解析、切片、Embedding、向量入库、向量检索和基础问答串起来了。到这里,RAG 已经不再只是一个“能回答”的 demo。

从 Day30 开始,重点要慢慢转向工程质量:

答案为什么可信  
错误为什么能定位  
效果为什么能比较  
成本为什么能估算  
部署为什么能复现  
项目为什么能讲清楚  

很多项目本地能跑,是因为你电脑上刚好装了数据库、环境变量、目录和依赖。Docker 化要把这些隐含前提写出来。


2. 先看一个业务场景

你把项目发给别人,对方没有 PostgreSQL,没有 pgvector,也不知道模型 Key 配在哪里。如果 README 只写“启动项目”,对方基本跑不起来。Compose 可以把应用、数据库、卷和环境变量组织成一套可复现环境。

这个场景里,最容易出错的地方通常不是某一行代码,而是链路边界没有想清楚。

输入是什么  
依赖哪份资料  
中间结果怎么保存  
失败时返回什么  
如何证明改动有效  

带着这些问题往下看,后面的设计就不会变成空泛理论。

这一节要先说明为什么要 Docker 化。

不是为了显得“部署专业”,而是为了解决环境不可复现的问题。

判断顺序可以这样写:

1. 先列出项目运行依赖:Java 服务、Python 服务、PostgreSQL、pgvector、Redis、模型配置  
2. 再判断哪些依赖适合容器化,哪些只需要环境变量配置  
3. Compose 文件要表达服务关系、端口、数据卷、健康检查和启动顺序  
4. 镜像里不要写死密钥,密钥通过环境变量或配置文件注入  
5. 最后用干净环境执行启动命令,证明别人也能跑起来  

它解决的是环境复现问题:代码在自己电脑能跑,但换一台机器就缺依赖、缺扩展、缺配置。


3. 核心概念

1. Dockerfile

负责把应用打成镜像。重点是固定基础镜像、多阶段构建、非 root 用户和健康检查。

可以把它记成一句话:镜像封装应用。

2. Docker Compose

负责组织多个服务,例如应用、PostgreSQL、Redis、Nginx。服务间通过服务名访问。

可以把它记成一句话:Compose 封装环境。

3. 数据卷

数据库数据必须放在 volume 中,容器重建不应丢数据。

可以把它记成一句话:数据不能跟容器生命绑定。

4. 配置注入

密钥和环境差异通过环境变量或 secret 注入,不写进镜像和仓库。

可以把它记成一句话:配置属于运行时。


4. 整体流程

graph TD;  
 A["构建应用镜像"] --> B["启动 PostgreSQL + pgvector"]; B["启动 PostgreSQL + pgvector"] --> C["执行数据库迁移"];  
 C["执行数据库迁移"] --> D["启动应用"];  
 D["启动应用"] --> E["健康检查"];  
 E["健康检查"] --> F["导入演示数据"];  
 F["导入演示数据"] --> G["运行问答冒烟"];  

图里每个节点都应该能单独打日志、单独统计耗时、单独写测试。

这就是我一直强调的:不要把 RAG 写成一个黑盒方法。黑盒方法演示时很爽,排查时很痛苦。


5. 落地步骤

1. 列出依赖

先写清项目依赖哪些服务、端口、环境变量、目录和模型配置。

落地时要留下可检查的产物:依赖清单。

2. 编写 Dockerfile

使用多阶段构建,运行阶段只保留必要文件,避免镜像过大。

落地时要留下可检查的产物:应用镜像。

3. 编写 Compose

定义数据库、应用、网络、volume、健康检查和依赖关系。

落地时要留下可检查的产物:compose.yaml。

4. 从零验证

在干净环境按 README 启动,导入演示文档并完成一次问答。

落地时要留下可检查的产物:启动验证记录。


6. 数据结构或配置示例

项目 说明
POSTGRES_DB 数据库名
POSTGRES_PASSWORD 数据库密码,敏感
SPRING_DATASOURCE_URL 应用连接数据库地址
MODEL_API_KEY 模型服务密钥,敏感
UPLOAD_DIR 文件上传目录或对象存储配置

如果项目里已经有自己的字段命名,可以不照抄这张表。但这些信息最好都能找到对应位置,否则排查问题时会缺证据。


7. 示例

services:  
 postgres: image: pgvector/pgvector:pg17 environment: POSTGRES_DB: rag POSTGRES_USER: rag_user POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data  
 app: image: rag-service:1.0.0 environment: SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/rag  
volumes:  
 postgres_data:  

示例的重点不是格式,而是思路:把规则、参数、输入、输出和失败状态显式写出来。


8. 为什么不能简单粗暴地做

不能只在 README 里写“先安装 PostgreSQL”。学习阶段可以手动装,但项目展示和交付阶段,最好把关键依赖容器化,减少环境差异。

很多初学者会希望有一个“最简单固定答案”。但 RAG 项目里,简单粗暴通常会把问题藏起来:短期好像能跑,长期很难维护。


9. 调试和排查路径

当结果不符合预期时,建议按这个顺序排查:

1. 输入问题是否正确  
2. 权限范围是否正确  
3. 检索候选是否包含正确证据  
4. 排序或过滤是否把正确证据丢掉  
5. Prompt 是否把证据清楚交给模型  
6. 模型是否按证据回答  
7. 引用是否能支持结论  
8. 日志、成本、耗时是否异常  

不要一看到答案不对就去改 Prompt。很多时候问题根本不在 Prompt,而是在解析、切片、过滤、召回或数据版本。


10. 工程取舍

  • Compose 适合学习、演示和单机部署。
  • 生产环境可以继续演进到云数据库或 Kubernetes。
  • Docker 简化环境,但不会自动解决数据库迁移和密钥管理。

取舍要写在文档里。因为过几周再回来看,你很可能只记得“当时这么做了”,却忘了“为什么这么做”。


11. 常见坑

  • 容器里还使用 localhost 连接数据库。
  • 把 API Key 写进 Dockerfile。
  • 数据库没有 volume。
  • 容器启动了但没有跑真实问答冒烟。

这些坑不是为了吓人,而是为了让你知道项目坏掉时从哪里下手。


12. 验收清单

  • ☐ 应用能打成镜像
  • ☐ PostgreSQL + pgvector 可启动
  • ☐ 数据库数据持久化
  • ☐ 密钥不进入镜像
  • ☐ 干净环境可完成一次问答

验收清单是博客里很有价值的部分。它能把一篇文章从“我讲了一个概念”变成“你可以跟着做出一个结果”。


13. 落地清单

  • ☐ 写 .env.example
  • ☐ 启动 pgvector 容器
  • ☐ 让应用用服务名连接数据库
  • ☐ 重启容器验证数据不丢

落地后,建议把结果截图或记录到项目文档里。后面写 README、博客复盘或项目说明时,这些都是现成素材。


14. 小结

Docker 化解决的是可复现问题。它让项目从“我电脑上能跑”变成“别人按步骤也能跑”。

到这里,你应该能把今天的主题讲成一个完整故事:为什么需要它、它解决哪一层问题、怎么落地、怎么验证、有什么代价。


15. 参考资料

  • Spring AI RAG
  • Spring AI ChatClient
  • Spring AI Advisors
  • LangChain RAG
  • PostgreSQL 全文检索
AI自学路线
AI
许可协议: 
分享

相关文章

7月 9, 2026

46 LangGraph State:设计可恢复的 Agent 状态

LangGraph State:设计可恢复的 Agent 状态 State 是 Agent 节点之间共享的数据契约。它决定任务能否暂停、恢复、测试和排查。

7月 9, 2026

45 业务接口设计:订单、工单、确认与日志 API

业务接口设计:订单、工单、确认与日志 API Agent 最终调用的是业务接口。接口越清楚,模型ว

7月 9, 2026

44 售后工单 Agent 需求分析

售后工单 Agent 需求分析 写 Agent 代码前,先把售后业务需求讲清楚:分类、知识库、订单、工单、确认和边界。 &

下一篇

43 Agent 与 Workflow:固定流程和动态决策的边界

上一篇

35 日志与成本:看清每一次 RAG 调用

最近更新

  • 46 LangGraph State:设计可恢复的 Agent 状态
  • 45 业务接口设计:订单、工单、确认与日志 API
  • 44 售后工单 Agent 需求分析
  • 43 Agent 与 Workflow:固定流程和动态决策的边界
  • 36 Docker 化:打包 RAG 应用与基础设施

热门标签

java基础 微服务 maven Spring Tomcat DDD Linux Linux基础 SQL基础 数据结构算法

目录

©2026 一条在知识海洋的咸鱼. 保留部分权利。

使用 Halo 主题 Chirpy