AI网关docker compose配置怎么写

文章导读
AI 网关的 docker compose 配置,难点通常不在 compose 语法,而在先确认三件事:网关镜像是否需要配套数据库、对外端口开放到什么范围、模型供应商的密钥放在哪里。把这三件事定下来,compose 文件本身一般只有几十行:一个网关服务、一个可选的数据库服务、把密钥交给 .env 注入、数据走 named volume、加一个 healthcheck。镜像名、端口、健康检查路径都要
📋 目录
  1. Ⅰ 先确认当前场景和目标
  2. Ⅱ 按这个顺序处理
  3. Ⅲ 改完后怎么验证
  4. Ⅳ 容易忽略的边界
A A

AI 网关的 docker compose 配置,难点通常不在 compose 语法,而在先确认三件事:网关镜像是否需要配套数据库、对外端口开放到什么范围、模型供应商的密钥放在哪里。把这三件事定下来,compose 文件本身一般只有几十行:一个网关服务、一个可选的数据库服务、把密钥交给 .env 注入、数据走 named volume、加一个 healthcheck。镜像名、端口、健康检查路径都要按你选的那款网关说明替换,不要照抄别人的文件。

建议先把网关拆成“网关容器 + 可选数据库 + .env 密钥 + named volume 数据”四块再写 compose。对外端口默认只绑 127.0.0.1 或内网地址,镜像固定 tag 不用 latest,密钥不写进 compose 明文。写完后先跑 docker compose config 校验,再起容器看日志和健康检查,最后发一个最小的对话请求确认链路通。数据库持久化、容器权限、端口暴露范围是三个最容易忽略的边界。

先确认当前场景和目标

同样是“装个 AI 网关”,单机自己试和内网多人共用,compose 写法差别不小。开始写文件前建议先确认下面几项,任何一项没定,后面都要返工:

  • 运行范围:只在本机调用,还是给同网段的其他服务用。这决定端口写 127.0.0.1:4000:4000 还是 0.0.0.0,也决定要不要额外做鉴权。
  • 是否带数据库:不少网关支持无数据库的单机模式(配置写文件),也支持接 Postgres 存密钥、模型清单和用量记录。带数据库就要多一个服务和一次初始化。
  • 密钥来源:上游模型供应商的 key、网关自身的访问 key,建议全部放 .env,compose 里只引用变量名。不要把真实 key 写进 environment 后提交到仓库。
  • 配置文件形式:有的网关用环境变量描述模型,有的要求挂载一个 yaml 配置文件。确认清楚是“挂文件”还是“配环境变量”,写错方向会一直起不来。

按这个顺序处理

建议按“目录 → .env → compose → 启动”的顺序推进,每一步都能单独检查,出错时容易定位。

第一步:建目录和 .env

在部署目录下放三个东西:docker-compose.yml、.env、可选的 config/ 目录。先写 .env,变量名按实际网关的要求替换:

AI网关docker compose配置怎么写
# .env 示例,变量名以所选网关说明为准
GATEWAY_IMAGE_TAG=1.0.0
GATEWAY_MASTER_KEY=换成一个足够长的随机串
PG_PASSWORD=换成一个独立密码
UPSTREAM_API_KEY=填上游模型服务的密钥

.env 建议加进 .gitignore,同时把权限收紧到只有部署用户可读。

第二步:写 compose 骨架

下面是一个通用骨架,以单网关 + Postgres 为例。镜像名、端口、健康检查路径、环境变量名都要换成你实际使用的那款网关的写法:

services:
  ai-gateway:
    image: your-gateway:${GATEWAY_IMAGE_TAG}
    restart: unless-stopped
    ports:
      - "127.0.0.1:4000:4000"
    env_file:
      - .env
    environment:
      - DATABASE_URL=postgresql://gateway:${PG_PASSWORD}@db:5432/gateway
    volumes:
      - ./config:/app/config:ro
      - gateway-data:/app/data
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://127.0.0.1:4000/health']
      interval: 30s
      timeout: 5s
      retries: 3

  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      - POSTGRES_USER=gateway
      - POSTGRES_PASSWORD=${PG_PASSWORD}
      - POSTGRES_DB=gateway
    volumes:
      - pg-data:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U gateway']
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  gateway-data:
  pg-data:

几个替换点说明:不需要数据库的网关,删掉 db 服务和 DATABASE_URL,同时去掉 depends_on;没有配置文件机制的网关,去掉 ./config 那行挂载;如果镜像里没有 curl,healthcheck 要换成容器内确实存在的命令,否则会一直显示 unhealthy。数据库端口不要映射到宿主机,容器之间走 compose 默认网络即可。

AI网关docker compose配置怎么写

第三步:启动

docker compose config      # 先渲染一遍,检查变量是否都替换成功
sudo docker compose up -d
docker compose ps
docker compose logs -f ai-gateway

docker compose config 会把 .env 代入后的最终配置打印出来,密钥为空或变量名拼错在这一步就能看出来,比直接起容器再翻日志省事。

改完后怎么验证

验证建议分三层,从容器状态到业务链路逐层确认,不要只看 up -d 没报错就当作完成。

  1. 容器层:docker compose ps 里网关和数据库都应处于 running,健康状态不是 unhealthy。如果一直是 starting 后转 unhealthy,先看 docker compose logs 里有没有连接数据库失败或配置文件解析失败的报错。
  2. 服务层:从宿主机请求健康检查接口,确认返回正常:curl -s http://127.0.0.1:4000/health。路径按实际网关替换,有的网关用 /healthz 或管理页根路径。
  3. 业务层:发一个最小对话请求,确认从网关到上游模型这一段也通。下面是通用骨架,模型名和路径要按网关文档替换:
    curl -s http://127.0.0.1:4000/v1/chat/completions \
      -H "Authorization: Bearer 你的网关访问密钥" \
      -H "Content-Type: application/json" \
      -d '{"model":"你在网关里配置的模型名","messages":[{"role":"user","content":"ping"}]}'

预期信号是:返回结构里带有模型回复内容而不是鉴权错误或 502。如果返回鉴权失败,先查网关访问密钥;如果返回上游错误,查 UPSTREAM_API_KEY 和上游服务地址是否可达。用量记录是否落库,可以重启一次容器后回管理页看数据是否还在,能保留说明 volume 生效。

容易忽略的边界

  • 镜像 tag:用 latest 时,某次 docker compose pull 可能把行为不一致的版本拉下来。建议固定到具体 tag,升级时先改 tag 再重启,出问题能改回去。
  • 数据库版本兼容:网关与 Postgres 大版本之间有兼容要求时,pg-data volume 里的数据不会跟着镜像自动升级。升级前先备份,不要直接换 postgres 大版本镜像。
  • 目录和文件权限:容器内以非 root 用户运行时,挂载进去的 config/ 读写权限、以及 named volume 的属主可能不匹配,表现为配置读不到或写入失败。先看日志里的 permission denied,再调整宿主机目录权限或容器用户。
  • 端口暴露:网关本身往往只有一层 key 校验,直接监听 0.0.0.0 且没有前置鉴权时,同网络内任何人都能调用并消耗你的上游额度。只在需要时放开,并考虑在前面加一层带鉴权的服务。
  • 回退方式:改配置前保留一份可用的 docker-compose.yml 副本。回退时用 docker compose down(不要加 -v)后换回旧文件重启,named volume 里的数据不会被删除;加 -v 会连同数据库一起清掉,这一步要格外注意。