:Docker 容器化与一键部署)
告别“本地跑得通换台机器就报错”的噩梦把你的 AI 系统打包成标准镜像01 引子经过前二十篇的实战你的MyAI项目已经非常强大了有 Spring Boot 应用有 PostgreSQL pgvector 向量数据库有 Redis 缓存服务在本地 IDEA 里它跑得完美无缺。但这存在一个致命问题它离不开你的电脑。如果让你把项目发给同事或者部署到云服务器上你需要对方手动安装 JDK 21、装 PostgreSQL、装 Redis还要配置各种网络和密码。稍微有一个环节版本不对系统就会崩溃。这一篇的目标使用 Docker 和 Docker Compose把应用、数据库、缓存打包成一个整体。别人拿到你的代码只需一行命令就能在世界上任何一台装了 Docker 的机器上完美运行。02 为什么是 Docker Compose对于单体应用用Dockerfile打个镜像就够了。但 AI 应用是一个微服务集群应用需要连接数据库应用需要连接 Redis数据库和 Redis 需要在同一个内部网络中互相通信docker-compose就是用来编排多容器的神器。我们只需要写一个 YAML 文件就能把这三个组件一键拉起并自动配置好内部的局域网。03 核心实现第一步编写多阶段Dockerfile在项目根目录新建Dockerfile。为了减小最终镜像的体积从 800MB 降到 200MB我们采用多阶段构建# # 阶段一构建阶段 (用 Maven 编译代码) # FROM maven:3.9-eclipse-temurin-21 AS builder WORKDIR /app # 先复制 pom.xml 并下载依赖利用 Docker 缓存代码变了依赖不用重新下 COPY pom.xml . RUN mvn dependency:go-offline -B # 再复制源码并打包 COPY src ./src RUN mvn clean package -DskipTests # # 阶段二运行阶段 (只保留 JRE 和打好的 jar 包) # FROM eclipse-temurin:21-jre-alpine WORKDIR /app # 从构建阶段把 Fat JAR 复制过来 COPY --frombuilder /app/target/myai-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar]第二步编写docker-compose.yml在项目根目录新建docker-compose.yml。这是整个微服务集群的“总指挥”services: # 1. Spring Boot AI 应用 myai-app: build: . container_name: myai-app ports: - 8080:8080 environment: # 关键容器内网络通信指向下方的服务名 - SPRING_DATASOURCE_URLjdbc:postgresql://pgvector-db:5432/myai - SPRING_DATA_REDIS_HOSTredis-cache # 从 .env 文件中读取 API Key避免代码明文泄露 - SPRING_AI_DASHSCOPE_API_KEY${DASHSCOPE_API_KEY} depends_on: pgvector-db: condition: service_healthy networks: - myai-network # 2. 向量数据库 pgvector-db: image: pgvector/pgvector:pg16 container_name: pgvector-db ports: - 5432:5432 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: 123456 POSTGRES_DB: myai volumes: - pgdata:/var/lib/postgresql/data # 数据持久化 healthcheck: test: [CMD-SHELL, pg_isready -U postgres -d myai] interval: 5s timeout: 5s retries: 5 networks: - myai-network # 3. Redis 缓存 redis-cache: image: redis:alpine container_name: redis-cache ports: - 6379:6379 volumes: - redisdata:/data networks: - myai-network volumes: pgdata: redisdata: networks: myai-network: driver: bridge第三步安全注入 API Key.env文件千万不要把 API Key 写死在docker-compose.yml或application.yml里否则代码传到 GitHub 上会立刻被盗刷。在根目录新建一个名为.env的文件写入真实 KeyDASHSCOPE_API_KEYsk-你的真实APIKey⚠️ 务必注意打开.gitignore文件加上一行.env。04 踩坑记录实战避坑在这一步很多 Java 开发者会踩两个极其经典的坑坑一no main manifest attribute, in app.jar现象容器启动瞬间退出日志报错找不到主清单属性。原因你的pom.xml中spring-boot-maven-plugin的configuration里可能写了skiptrue/skip。这会导致 Maven 只打了一个普通 JAR而不是可执行的 Fat JAR。解决删掉skiptrue/skip或者确保包含goalrepackage/goal。坑二DashScope API key must be set现象应用启动报错说环境里找不到 API Key。原因Spring Boot 的环境变量映射机制要求非常严格。在docker-compose.yml中注入的变量名必须全大写且用下划线。解决Spring Boot 会将SPRING_AI_DASHSCOPE_API_KEY自动映射为spring.ai.dashscope.api-key。千万不要写成别的奇奇怪怪的名字。05 一键启动修改完代码和配置后在 IDEA 的终端里执行docker-compose up -d --build你会看到什么Docker 会按照Dockerfile的步骤自动下载 Maven 环境编译你的代码打包镜像。自动去云端拉取 PostgreSQL 和 Redis 镜像。创建内部网络。依次启动三个容器。等终端出现绿色的 Running后打开 Docker Desktop你会看到三个容器整整齐齐地跑在myai-network下。此时你访问http://localhost:8080/api/thread/info接口完美响应06 成果总结到这一步你已经彻底打通了 Java AI 应用交付的“最后一公里”能力状态多阶段构建✅ 镜像瘦身环境隔离✅ 容器化部署网络互通✅ 服务名互连数据持久化✅ Volume 挂载密钥安全✅.env注入现在你的项目已经是一个开箱即用的开源级作品。任何人下载你的代码只需docker-compose up -d无需任何复杂配置就能完美体验你的智能体。07 下期预告部署上线后应用是跑起来了但你怎么知道它跑得好不好如果用户的某次提问卡了 10 秒或者调用的 Token 突然暴增你在本地终端是看不到这些数据的。下一篇AI 应用的可观测性——链路追踪与监控告警。我们将引入 Micrometer 和 Prometheus把你的 AI 应用彻底变成“透明”的。 我是超超不吵吵10年 Java 全栈正在转型 AI 应用开发。每周一篇实战笔记不贩卖焦虑只分享能落地的技术。全网同名欢迎关注。