从零把 AI 聊天工具打包上线:Docker 部署实战与完整源码
AI工具 Docker部署教程|附源码
在 AI 应用快速发展的今天,越来越多开发者会把大模型能力集成到自己的工具、网站、后台系统或自动化流程中。例如:AI 聊天助手、文档总结工具、代码解释器、知识库问答机器人、图片生成助手等。
但是,很多 AI 工具在本地运行时会遇到一些常见问题:
- 不同电脑环境不一致;
- Python、Node.js 版本冲突;
- 依赖包安装失败;
- 部署到服务器后无法稳定运行;
- 项目迁移困难;
- 线上环境和本地环境不一致。
为了解决这些问题,Docker 是非常适合 AI 工具部署的一种方案。它可以把项目运行环境、依赖、配置统一打包成镜像,在任何支持 Docker 的机器上快速启动。
本文将以一个简单的 AI 聊天接口服务 为例,完整讲解如何使用 Docker 部署 AI 工具,并附上完整源码示例。
一、本文实现的 AI 工具功能
本文我们将实现一个简单的 AI 工具服务,主要包含以下功能:
- 提供一个 HTTP API 接口;
- 前端或其他系统可以通过接口提交问题;
- 后端调用 AI 模型接口;
- 返回 AI 生成的回答;
- 支持 Docker 镜像构建;
- 支持 Docker Compose 一键部署;
- 支持环境变量配置 API Key;
- 支持生产环境部署到服务器。
为了便于演示,本文使用 Python + FastAPI 开发后端服务。FastAPI 轻量、性能好、文档友好,非常适合 AI 工具类项目。
项目结构如下:
ai-tool-docker-demo/
├── app/
│ ├── main.py
│ └── ai_client.py
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
├── .env.example
└── README.md
二、为什么 AI 工具适合用 Docker 部署?
AI 工具通常会涉及多种依赖,例如:
- Python 运行环境;
- AI SDK;
- Web 框架;
- 数据库;
- 向量数据库;
- 缓存服务;
- 模型文件;
- GPU 驱动;
- 环境变量配置。
如果直接在服务器上手动安装,容易出现版本不兼容问题。比如本地 Python 是 3.11,服务器是 3.8;本地依赖包能安装,服务器安装时报错;本地运行正常,部署后接口异常。
Docker 的优势在于:
1. 环境一致
Docker 镜像中包含应用运行所需的环境、依赖和代码。只要镜像构建成功,在其他机器上运行时环境基本一致。
2. 部署简单
传统部署可能需要安装 Python、配置虚拟环境、安装依赖、启动进程管理器等。而 Docker 部署只需要:
docker compose up -d
即可启动服务。
3. 方便迁移
项目需要从一台服务器迁移到另一台服务器时,只需要复制代码或镜像,然后重新启动容器即可。
4. 易于扩展
如果 AI 工具访问量变大,可以通过多个容器实例进行扩展,也可以结合 Nginx、Kubernetes 等工具进行负载均衡。
5. 便于版本管理
每次发布可以构建不同版本的镜像,例如:
ai-tool:v1.0.0
ai-tool:v1.1.0
ai-tool:v2.0.0
出现问题时也可以快速回滚到旧版本。
三、准备工作
在开始之前,请确保你的电脑或服务器已经安装以下工具:
1. Docker
可以通过以下命令查看 Docker 是否安装成功:
docker -v
如果输出类似:
Docker version 26.1.0, build xxxxx
说明 Docker 已安装。
2. Docker Compose
新版 Docker 通常已经内置 Compose 插件,可以执行:
docker compose version
如果输出版本号,说明可用。
3. AI 模型 API Key
本文示例中会通过环境变量读取 API Key。你可以使用任意兼容的 AI 服务接口,例如 OpenAI、DeepSeek、通义千问、智谱、月之暗面等。
为了让源码更通用,示例代码采用标准 HTTP 请求方式调用模型接口,你可以根据实际平台调整接口地址和参数。
四、创建项目目录
首先创建项目目录:
mkdir ai-tool-docker-demo
cd ai-tool-docker-demo
创建子目录:
mkdir app
最终我们会在其中编写 Python 服务代码。
五、编写后端源码
1. 编写 requirements.txt
在项目根目录下创建 requirements.txt:
fastapi==0.115.0
uvicorn[standard]==0.30.6
python-dotenv==1.0.1
requests==2.32.3
依赖说明:
fastapi:Web API 框架;uvicorn:ASGI 服务,用于启动 FastAPI;python-dotenv:用于本地读取.env配置;requests:用于调用 AI 模型接口。
2. 编写 app/ai_client.py
在 app 目录下创建 ai_client.py:
import os
import requests
class AIClient:
def __init__(self):
self.api_key = os.getenv("AI_API_KEY", "")
self.api_base_url = os.getenv("AI_API_BASE_URL", "https://api.openai.com/v1/chat/completions")
self.model = os.getenv("AI_MODEL", "gpt-4o-mini")
if not self.api_key:
print("Warning: AI_API_KEY is empty. Please set it in environment variables.")
def chat(self, message: str) -> str:
"""
调用 AI 模型接口,返回模型回复内容。
这里使用通用 Chat Completions 格式,具体字段可根据服务商调整。
"""
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
payload = {
"model": self.model,
"messages": [
{
"role": "system",
"content": "你是一个专业、简洁、友好的 AI 助手。"
},
{
"role": "user",
"content": message
}
],
"temperature": 0.7
}
try:
response = requests.post(
self.api_base_url,
headers=headers,
json=payload,
timeout=60
)
response.raise_for_status()
data = response.json()
return data["choices"][0]["message"]["content"]
except requests.exceptions.RequestException as e:
return f"AI 接口请求失败:{str(e)}"
except KeyError:
return "AI 接口返回格式异常,请检查模型服务商返回数据结构。"
这段代码主要负责调用外部 AI 接口。它会读取以下环境变量:
AI_API_KEY
AI_API_BASE_URL
AI_MODEL
这样做的好处是代码不需要写死模型服务商信息,也避免了把 API Key 暴露在源码中。
3. 编写 app/main.py
继续创建 app/main.py:
from fastapi import FastAPI
from pydantic import BaseModel
from app.ai_client import AIClient
app = FastAPI(
title="AI Tool Docker Demo",
description="一个使用 FastAPI + Docker 部署的 AI 工具示例",
version="1.0.0"
)
class ChatRequest(BaseModel):
message: str
class ChatResponse(BaseModel):
reply: str
ai_client = AIClient()
@app.get("/")
def index():
return {
"name": "AI Tool Docker Demo",
"version": "1.0.0",
"status": "running"
}
@app.get("/health")
def health_check():
return {
"status": "ok"
}
@app.post("/chat", response_model=ChatResponse)
def chat(request: ChatRequest):
reply = ai_client.chat(request.message)
return ChatResponse(reply=reply)
这里定义了三个接口:
| 接口 | 方法 | 作用 |
|---|---|---|
/ |
GET | 查看服务基本信息 |
/health |
GET | 健康检查 |
/chat |
POST | 调用 AI 聊天接口 |
其中 /chat 是核心接口。
请求示例:
{
"message": "请用一句话介绍 Docker 的作用"
}
返回示例:
{
"reply": "Docker 可以将应用及其依赖打包到容器中,从而实现快速、一致、可移植的部署。"
}
六、编写环境变量文件
在项目根目录创建 .env.example:
AI_API_KEY=your_api_key_here
AI_API_BASE_URL=https://api.openai.com/v1/chat/completions
AI_MODEL=gpt-4o-mini
APP_PORT=8000
部署时复制一份:
cp .env.example .env
然后编辑 .env:
AI_API_KEY=你的真实APIKey
AI_API_BASE_URL=你的模型接口地址
AI_MODEL=你的模型名称
APP_PORT=8000
注意:不要把真实 .env 文件提交到公开代码仓库。
七、编写 Dockerfile
在项目根目录创建 Dockerfile:
FROM python:3.11-slim
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Dockerfile 说明
FROM python:3.11-slim
使用 Python 3.11 的精简镜像,体积较小,适合部署。
WORKDIR /app
设置容器内部工作目录为 /app。
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
先复制依赖文件并安装依赖。这样做可以利用 Docker 缓存,只要依赖没有变化,后续构建会更快。
COPY . .
复制项目源码到容器中。
EXPOSE 8000
声明服务监听 8000 端口。
CMD [...]
容器启动后执行 FastAPI 服务。
八、编写 Docker Compose 配置
在项目根目录创建 docker-compose.yml:
services:
ai-tool:
build:
context: .
dockerfile: Dockerfile
container_name: ai-tool-demo
ports:
- "${APP_PORT:-8000}:8000"
env_file:
- .env
restart: unless-stopped
配置说明:
build:表示从当前目录构建镜像;container_name:容器名称;ports:将宿主机端口映射到容器端口;env_file:读取.env文件中的环境变量;restart: unless-stopped:容器异常退出后自动重启。
九、本地运行测试
1. 复制环境变量文件
cp .env.example .env
修改 .env,填入真实 API Key。
2. 使用 Docker Compose 启动
docker compose up -d --build
参数说明:
up:启动服务;-d:后台运行;--build:启动前重新构建镜像。
3. 查看容器状态
docker ps
如果看到类似输出:
CONTAINER ID IMAGE PORTS
xxxxxxx ai-tool-docker-demo-ai-tool 0.0.0.0:8000->8000/tcp
说明服务启动成功。
4. 查看日志
docker logs -f ai-tool-demo
如果看到 Uvicorn 启动日志,表示接口服务正常运行。
十、接口测试
1. 测试首页接口
curl http://localhost:8000/
返回:
{
"name": "AI Tool Docker Demo",
"version": "1.0.0",
"status": "running"
}
2. 测试健康检查接口
curl http://localhost:8000/health
返回:
{
"status": "ok"
}
3. 测试 AI 聊天接口
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"message":"请用通俗的话解释什么是容器化部署"}'
返回示例:
{
"reply": "容器化部署就是把应用程序和它需要的运行环境一起打包起来,让它可以在不同服务器上以相同方式运行。"
}
十一、访问 FastAPI 自动文档
FastAPI 默认提供接口文档。启动服务后,可以在浏览器访问:
http://localhost:8000/docs
你会看到 Swagger UI 页面,可以直接在网页上测试 /chat 接口。
也可以访问:
http://localhost:8000/redoc
查看 ReDoc 风格的 API 文档。
这对于 AI 工具开发非常方便,尤其是在前后端联调时,可以快速确认接口字段和返回格式。
十二、服务器部署流程
如果要部署到云服务器,推荐流程如下。
1. 安装 Docker
以 Ubuntu 为例:
sudo apt update
sudo apt install -y docker.io docker-compose-plugin
启动 Docker:
sudo systemctl enable docker
sudo systemctl start docker
查看版本:
docker -v
docker compose version
2. 上传项目代码
可以使用 Git:
git clone https://你的仓库地址/ai-tool-docker-demo.git
cd ai-tool-docker-demo
也可以使用 scp 上传:
scp -r ai-tool-docker-demo root@服务器IP:/opt/
3. 配置环境变量
cp .env.example .env
vim .env
填入真实 API Key:
AI_API_KEY=sk-xxxxxxxx
AI_API_BASE_URL=https://api.openai.com/v1/chat/completions
AI_MODEL=gpt-4o-mini
APP_PORT=8000
4. 启动服务
docker compose up -d --build
5. 开放服务器端口
如果服务器有安全组,需要开放 8000 端口。
以云服务器控制台为例,需要添加入站规则:
协议:TCP
端口:8000
来源:你的IP 或 0.0.0.0/0
如果使用 Ubuntu 防火墙:
sudo ufw allow 8000
6. 访问服务
浏览器访问:
http://服务器IP:8000/docs
如果能看到接口文档,说明部署成功。
十三、添加 Nginx 反向代理
生产环境通常不建议直接暴露 8000 端口,而是使用 Nginx 反向代理到容器服务。
假设域名为:
ai.example.com
Nginx 配置示例:
server {
listen 80;
server_name ai.example.com;
location / {
proxy_pass http://127.0.0.1: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;
}
}
保存后重载 Nginx:
sudo nginx -t
sudo systemctl reload nginx
如果需要 HTTPS,可以使用 Certbot 申请免费证书:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d ai.example.com
配置完成后,就可以通过:
https://ai.example.com
访问 AI 工具服务。
十四、生产环境优化建议
1. 不要把 API Key 写进代码
API Key 应通过环境变量传入,例如 .env 文件、服务器环境变量、Kubernetes Secret 等。
错误示例:
api_key = "sk-xxxxxxx"
正确示例:
api_key = os.getenv("AI_API_KEY")
2. 增加请求鉴权
如果你的 AI 工具对外开放,建议增加接口鉴权,否则任何人都可以调用你的接口,造成费用损耗。
可以在请求头中增加一个 X-API-Token:
import os
from fastapi import Header, HTTPException
APP_TOKEN = os.getenv("APP_TOKEN", "")
def verify_token(x_api_token: str = Header(default="")):
if APP_TOKEN and x_api_token != APP_TOKEN:
raise HTTPException(status_code=401, detail="Invalid token")
然后在接口中使用依赖校验。
3. 增加日志记录
建议记录以下信息:
- 请求时间;
- 请求 IP;
- 请求接口;
- 模型名称;
- 响应耗时;
- 异常信息。
但不要记录用户敏感数据和 API Key。
4. 设置超时时间
调用 AI 模型接口时一定要设置 timeout,避免请求长时间阻塞:
requests.post(url, json=payload, timeout=60)
5. 限流
如果接口公开访问,可以增加限流策略。例如:
- 单 IP 每分钟最多请求 20 次;
- 单用户每天最多调用 100 次;
- 超过限制后返回 429。
6. 数据持久化
如果 AI 工具需要保存聊天记录、用户信息或任务记录,可以接入数据库:
- PostgreSQL;
- MySQL;
- MongoDB;
- Redis;
- SQLite。
如果使用 Docker Compose,也可以把数据库作为另一个服务一起部署。
十五、常见问题排查
1. 容器启动失败
查看日志:
docker logs -f ai-tool-demo
常见原因:
- Python 依赖安装失败;
- 端口被占用;
.env文件不存在;- 代码路径错误;
- Dockerfile 中启动命令写错。
2. 访问不到接口
检查容器是否运行:
docker ps
检查端口映射:
docker compose ps
检查防火墙和云服务器安全组是否开放端口。
3. AI 接口返回 401
通常是 API Key 错误或没有权限。请检查:
AI_API_KEY=你的真实APIKey
同时确认服务商是否要求特定接口地址。
4. AI 接口返回格式异常
不同模型服务商返回格式可能略有不同。本文示例使用的是类似 OpenAI Chat Completions 的返回结构:
data["choices"][0]["message"]["content"]
如果你的服务商返回字段不同,需要修改 ai_client.py 中的解析逻辑。
5. Docker 构建速度慢
可以尝试配置镜像源,或者减少依赖体积。也可以使用更合理的 Dockerfile 缓存策略,例如先复制 requirements.txt 再复制源码。
十六、完整源码汇总
下面是本文项目的完整源码。
requirements.txt
fastapi==0.115.0
uvicorn[standard]==0.30.6
python-dotenv==1.0.1
requests==2.32.3
app/ai_client.py
import os
import requests
class AIClient:
def __init__(self):
self.api_key = os.getenv("AI_API_KEY", "")
self.api_base_url = os.getenv("AI_API_BASE_URL", "https://api.openai.com/v1/chat/completions")
self.model = os.getenv("AI_MODEL", "gpt-4o-mini")
if not self.api_key:
print("Warning: AI_API_KEY is empty. Please set it in environment variables.")
def chat(self, message: str) -> str:
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
payload = {
"model": self.model,
"messages": [
{
"role": "system",
"content": "你是一个专业、简洁、友好的 AI 助手。"
},
{
"role": "user",
"content": message
}
],
"temperature": 0.7
}
try:
response = requests.post(
self.api_base_url,
headers=headers,
json=payload,
timeout=60
)
response.raise_for_status()
data = response.json()
return data["choices"][0]["message"]["content"]
except requests.exceptions.RequestException as e:
return f"AI 接口请求失败:{str(e)}"
except KeyError:
return "AI 接口返回格式异常,请检查模型服务商返回数据结构。"
app/main.py
from fastapi import FastAPI
from pydantic import BaseModel
from app.ai_client import AIClient
app = FastAPI(
title="AI Tool Docker Demo",
description="一个使用 FastAPI + Docker 部署的 AI 工具示例",
version="1.0.0"
)
class ChatRequest(BaseModel):
message: str
class ChatResponse(BaseModel):
reply: str
ai_client = AIClient()
@app.get("/")
def index():
return {
"name": "AI Tool Docker Demo",
"version": "1.0.0",
"status": "running"
}
@app.get("/health")
def health_check():
return {
"status": "ok"
}
@app.post("/chat", response_model=ChatResponse)
def chat(request: ChatRequest):
reply = ai_client.chat(request.message)
return ChatResponse(reply=reply)
.env.example
AI_API_KEY=your_api_key_here
AI_API_BASE_URL=https://api.openai.com/v1/chat/completions
AI_MODEL=gpt-4o-mini
APP_PORT=8000
Dockerfile
FROM python:3.11-slim
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
docker-compose.yml
services:
ai-tool:
build:
context: .
dockerfile: Dockerfile
container_name: ai-tool-demo
ports:
- "${APP_PORT:-8000}:8000"
env_file:
- .env
restart: unless-stopped
十七、总结
本文从零开始演示了一个 AI 工具的 Docker 部署流程,包括项目结构设计、FastAPI 接口开发、AI 接口调用、Dockerfile 编写、Docker Compose 一键启动、本地测试、服务器部署、Nginx 反向代理以及生产环境优化建议。
使用 Docker 部署 AI 工具的核心优势是:环境统一、部署简单、迁移方便、易于扩展、便于维护。
如果你正在开发 AI 聊天助手、知识库问答、文档总结、代码生成、智能客服等工具,都可以参考本文的方式进行封装和部署。后续如果需要进一步增强,可以继续加入用户系统、数据库、向量检索、流式输出、接口鉴权、调用统计和费用控制等功能,让这个基础 AI 工具逐步演进为完整的生产级 AI 应用。