超超不吵吵头像
Java AI转型实战(二十一):Docker 容器化与一键部署封面图

Java AI转型实战(二十一):Docker 容器化与一键部署

告别“本地跑得通,换台机器就报错”的噩梦,把你的 AI 系统打包成标准镜像

01 引子

经过前二十篇的实战,你的 MyAI 项目已经非常强大了:

  • 有 Spring Boot 应用

  • 有 PostgreSQL + pgvector 向量数据库

  • 有 Redis 缓存服务

在本地 IDEA 里,它跑得完美无缺。但这存在一个致命问题:它离不开你的电脑。

如果让你把项目发给同事,或者部署到云服务器上,你需要对方手动安装 JDK 21、装 PostgreSQL、装 Redis,还要配置各种网络和密码。稍微有一个环节版本不对,系统就会崩溃。

这一篇的目标:使用 Docker 和 Docker Compose,把应用、数据库、缓存打包成一个整体。别人拿到你的代码,只需一行命令,就能在世界上任何一台装了 Docker 的机器上完美运行。


02 为什么是 Docker Compose?

对于单体应用,用 Dockerfile 打个镜像就够了。但 AI 应用是一个微服务集群:

  1. 应用需要连接数据库

  2. 应用需要连接 Redis

  3. 数据库和 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 --from=builder /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_URL=jdbc:postgresql://pgvector-db:5432/myai
      - SPRING_DATA_REDIS_HOST=redis-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 的文件,写入真实 Key:

DASHSCOPE_API_KEY=sk-你的真实APIKey

⚠️ 务必注意:打开 .gitignore 文件,加上一行 .env。


04 踩坑记录(实战避坑)

在这一步,很多 Java 开发者会踩两个极其经典的坑:

坑一:no main manifest attribute, in app.jar

现象:容器启动瞬间退出,日志报错找不到主清单属性。
原因:你的 pom.xml 中 spring-boot-maven-plugin 的 <configuration> 里,可能写了 <skip>true</skip>。这会导致 Maven 只打了一个普通 JAR,而不是可执行的 Fat JAR。
解决:删掉 <skip>true</skip>,或者确保包含 <goal>repackage</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

你会看到什么?

  1. Docker 会按照 Dockerfile 的步骤,自动下载 Maven 环境,编译你的代码,打包镜像。

  2. 自动去云端拉取 PostgreSQL 和 Redis 镜像。

  3. 创建内部网络。

  4. 依次启动三个容器。

等终端出现绿色的 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 应用开发。
每周一篇实战笔记,不贩卖焦虑,只分享能落地的技术。
全网同名,欢迎关注。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/shizhewan_2/article/details/168655775

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--