前言
上篇文章我们已经讲过如何从0开始搭建一个AI agent,今天我们再来具体操作如何将你的智能体部署到服务器,实现线上访问。
适用场景: CentOS 7 + Docker + Nginx 反向代理
服务器配置: 最低 2 核 CPU / 2GB 内存
部署架构: FastAPI 后端 + Streamlit 前端 + Chroma 向量数据库
目录
部署架构概览
技术栈
| 组件 | 技术选型 | 说明 |
|---|---|---|
| 后端框架 | FastAPI + Uvicorn | 异步 Web 框架,支持 SSE 流式响应 |
| 前端界面 | Streamlit | 快速构建交互式 Web 应用 |
| 向量数据库 | ChromaDB | 本地持久化向量存储 |
| LLM 服务 | 阿里云 DashScope | 通义千问大模型 API |
| 容器化 | Docker + Docker Compose | 统一运行环境 |
| 反向代理 | Nginx | 处理 HTTP 请求转发和 SSE 流式传输 |
数据持久化
- 向量数据库:
./chroma_db和./rag/chroma_db挂载到容器 - 知识库文件:
./data目录存放 PDF/TXT 原始文档 - 日志文件:
./logs目录记录运行日志 - 环境变量:
.env文件只读挂载,保护敏感信息
第一步:本地环境准备
1.1 确认项目依赖
创建依赖文件 requirements.txt 根据项目情况检查是否包含核心依赖,以下以我自己的agent为例:
fastapi
uvicorn[standard]
langchain
langchain-core
langchain-community
langchain-chroma
langchain-text-splitters
dashscope
chromadb
pypdf
pydantic
python-dotenv
pyyaml
loguru
streamlit
1.2 创建 Dockerfile
在项目根目录创建 Dockerfile,定义容器镜像构建规则:
FROM python:3.11-slim
WORKDIR /app
# 安装系统依赖(编译工具和 OpenMP 库)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential libgomp1 \
&& rm -rf /var/lib/apt/lists/* && apt-get clean
# 安装 Python 依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt && pip cache purge
# 复制项目代码
COPY . .
# 创建必要的目录
RUN mkdir -p /app/chroma_db /app/rag/chroma_db /app/logs
# 暴露端口
EXPOSE 8000 8501
# 默认启动命令(docker-compose 会覆盖此命令)
CMD ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"]
1.3 创建 docker-compose.yml
在项目根目录创建 docker-compose.yml,定义服务编排配置:
services:
learn-agent:
build:
context: .
dockerfile: Dockerfile
container_name: learn-agent
ports:
- "8000:8000" # FastAPI 后端
- "8501:8501" # Streamlit 前端
volumes:
- ./chroma_db:/app/chroma_db
- ./rag/chroma_db:/app/rag/chroma_db
- ./data:/app/data
- ./logs:/app/logs
- ./.env:/app/.env:ro
dns:
- 223.6.6.6 # 阿里云公共 DNS
- 8.8.8.8 # Google 公共 DNS
command: >
sh -c "uvicorn api.main:app --host 0.0.0.0 --port 8000 &
streamlit run app.py --server.address 0.0.0.0 --server.port 8501"
restart: unless-stopped
mem_limit: 1500m # 内存限制
cpus: 1.5 # CPU 限制
关键配置说明:
dns配置: 解决容器内无法解析dashscope.aliyuncs.com的问题command覆盖: 同时启动 FastAPI 和 Streamlit 两个服务- 资源限制: 适配 2GB 内存服务器,预留 500MB 给系统
1.4 创建 .dockerignore
在项目根目录创建 .dockerignore,排除不需要打包的文件:
__pycache__/
*.pyc
.venv/
.env
.idea/
.git/
logs/
node_modules/
frontend/
chroma_db/
rag/chroma_db/
排除原因:
chroma_db/和rag/chroma_db/:向量库文件在服务器上重新生成,避免文件锁定问题.env:包含敏感信息,单独上传frontend/:前端独立部署,不放入后端容器
1.5 打包并上传到服务器
方式一:使用 PowerShell 压缩
# 在项目根目录执行
Compress-Archive -Path * -DestinationPath deploy.zip -Force
方式二:使用 7-Zip 或 WinRAR
手动压缩时,确保排除 .dockerignore 中列出的目录和文件。
上传到服务器:
# 在本地 Git Bash 或 PowerShell 执行
scp D:/PythonProject/你的智能体项目文件夹/deploy.zip root@你的服务器IP:/root/
第二步:服务器环境部署
2.1 更新系统软件包
sudo yum update -y
2.2 安装 Docker CE
卸载旧版本(如有):
sudo yum remove -y docker docker-client docker-client-latest \
docker-common docker-latest docker-latest-logrotate \
docker-logrotate docker-engine
添加阿里云 Docker CE 镜像源:
国内网络环境下,使用阿里云镜像源可显著提升下载速度。
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装 Docker CE 及 Docker Compose 插件:
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
2.3 配置 Docker 守护进程
创建 /etc/docker/daemon.json 配置文件:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null << 'EOF'
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me",
"https://mirror.ccs.tencentyun.com"
],
"iptables": true
}
EOF
配置说明:
registry-mirrors: 配置 Docker Hub 镜像加速,解决国内访问超时问题iptables: true: 允许 Docker 管理 iptables 规则,避免与 firewalld 冲突
2.4 关闭系统防火墙
CentOS 7 默认启用 firewalld,与 Docker 的 iptables 规则存在冲突,会导致容器端口映射失败。
sudo systemctl stop firewalld
sudo systemctl disable firewalld
错误示例(未关闭防火墙时):
iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8000
-j DNAT --to-destination 172.18.0.2:8000 ! -i br-512396465b1d:
iptables: No chain/target/match by that name.
2.5 启动 Docker 服务
sudo systemctl daemon-reload
sudo systemctl start docker
sudo systemctl enable docker
验证安装:
sudo docker run --rm hello-world
看到 Hello from Docker! 即表示安装成功。
2.6 解压项目文件
cd /root
unzip deploy.zip -d /data/shier_agent
cd /data/shier_agent
2.7 上传环境变量文件
重要: 不要在服务器上手动创建
.env文件,使用 heredoc 粘贴内容会导致编码损坏。
在本地执行:
scp D:/PythonProject/你的项目文件夹/.env root@你的服务器IP:/data/shier_agent/.env
在服务器上验证:
cat /data/shier_agent/.env
确认内容格式正确,无乱码:
ANTHROPIC_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
ANTHROPIC_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
LANGSMITH_API_KEY=lsv2_pt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ZHIPU_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxx
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
2.8 创建必要的目录
mkdir -p /data/shier_agent/data
mkdir -p /data/shier_agent/logs
mkdir -p /data/shier_agent/chroma_db
mkdir -p /data/shier_agent/rag/chroma_db
2.9 配置系统 Swap
2GB 内存服务器建议开启 Swap,防止容器因内存不足被 OOM Kill。
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
验证 Swap 状态:
free -h
输出示例:
total used free shared buff/cache available
Mem: 1.8G 800M 200M 10M 800M 900M
Swap: 2.0G 0B 2.0G
2.10 清理旧容器和网络
如果之前有启动失败的容器,需先清理:
cd /data/shier_agent
sudo docker ps -a | grep learn-agent
sudo docker rm -f learn-agent 2>/dev/null
sudo docker network prune -f
2.11 构建 Docker 镜像
cd /data/shier_agent
sudo docker compose build
注意: 首次构建需要下载 Python 基础镜像(约 150MB)和安装依赖包,耗时约 20~40 分钟,请耐心等待。
2.12 启动容器
sudo docker compose up -d
2.13 查看启动日志
sudo docker compose logs -f
成功启动的标志:
learn-agent | INFO: Application startup complete.
learn-agent | INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
learn-agent |
learn-agent | You can now view your Streamlit app in your browser.
learn-agent |
learn-agent | Local URL: http://localhost:8501
learn-agent | Network URL: http://172.18.0.2:8501
按 Ctrl+C 退出日志查看。
2.14 安装 Nginx
sudo yum install -y nginx
2.15 配置 Nginx 反向代理
使用 sudo tee 直接写入配置文件(CentOS 7 默认无 nano 编辑器):
sudo tee /etc/nginx/nginx.conf > /dev/null << 'EOF'
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream api_backend {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name _;
# FastAPI 后端 - SSE 流式对话接口
location /api/ {
proxy_pass http://api_backend;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection '';
proxy_buffering off; # 关键:禁用缓冲,支持 SSE 流式传输
proxy_cache off;
chunked_transfer_encoding on;
}
# 健康检查接口
location /health {
proxy_pass http://api_backend;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Streamlit 前端
location / {
proxy_pass http://127.0.0.1:8501;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400; # WebSocket 长连接超时时间
proxy_buffering off;
}
}
}
EOF
配置要点:
- SSE 流式传输:
proxy_buffering off和chunked_transfer_encoding on确保实时响应 - WebSocket 支持:
Upgrade和Connection头部支持 Streamlit 的 WebSocket 连接 - 长连接超时:
proxy_read_timeout 86400设置为 24 小时,避免长时间对话中断
2.16 启动 Nginx
sudo nginx -t # 验证配置文件语法
sudo systemctl start nginx # 启动服务
sudo systemctl enable nginx # 设置开机自启
2.17 配置防火墙(可选)
由于步骤 2.4 已关闭 firewalld,此步骤可跳过。如需使用 firewalld,执行:
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --reload
2.18 配置云服务器安全组
登录阿里云控制台,配置 ECS 实例安全组:
- 进入 云服务器 ECS → 实例 → 安全组
- 点击 配置规则 → 添加入方向规则
- 填写规则:
- 端口范围:
80/80 - 授权对象:
0.0.0.0/0 - 协议类型:
TCP - 描述:
HTTP 服务
- 端口范围:
第三步:部署验证
3.1 服务器本地验证
# 1. 检查 Docker 容器状态
sudo docker ps
# 2. 验证 FastAPI 后端
curl http://127.0.0.1:8000/health
# 3. 验证 Streamlit 前端
curl http://127.0.0.1:8501
# 4. 验证 Nginx 代理
curl http://127.0.0.1/health
预期输出:
{"status":"healthy"}
3.2 浏览器访问验证
| 服务 | 访问地址 | 说明 |
|---|---|---|
| Streamlit 前端 | http://你的服务器IP/ | 智能客服对话界面 |
| API 健康检查 | http://你的服务器IP/health | 返回 {"status":"healthy"} |
| RAG 检索测试 | http://你的服务器IP/api/rag/retrieve?query=测试&top_k=3 | 测试向量检索功能 |
3.3 上传知识库并验证 RAG
如果 RAG 检索返回 {"documents": [], "count": 0},说明知识库未加载。
步骤一:上传知识库文件
# 在本地执行
scp -r D:/PythonProject/你的项目文件夹/data/* root@你的服务器IP:/data/shier_agent/data/
步骤二:触发知识库重载
curl -X POST http://你的服务器IP:8000/api/knowledge/reload
步骤三:查看重载状态
curl http://你的服务器IP:8000/api/knowledge/reload/status
步骤四:验证检索功能
curl "http://你的服务器IP:8000/api/rag/retrieve?query=怎么保养扫地机器人&top_k=3"
成功响应示例:
{
"query": "怎么保养扫地机器人",
"documents": [
{
"content": "定期清理尘盒和滤网...",
"metadata": {"source": "manual.pdf", "page": 12}
}
],
"count": 3
}
第四步:项目更新流程
4.1 本地代码修改后上传
方式一:分模块上传(推荐)
适用于小范围代码变更,上传速度快:
# 在本地执行,仅上传变更的模块
scp -r D:/PythonProject/你的项目文件夹/api root@你的服务器IP:/data/shier_agent/
scp -r D:/PythonProject/你的项目文件夹/agent root@你的服务器IP:/data/shier_agent/
scp -r D:/PythonProject/你的项目文件夹/rag root@你的服务器IP:/data/shier_agent/
scp -r D:/PythonProject/你的项目文件夹/model root@你的服务器IP:/data/shier_agent/
scp -r D:/PythonProject/你的项目文件夹/config root@你的服务器IP:/data/shier_agent/
scp -r D:/PythonProject/你的项目文件夹/utils root@你的服务器IP:/data/shier_agent/
scp D:/PythonProject/你的项目文件夹/app.py root@你的服务器IP:/data/shier_agent/
方式二:完整同步(适用于大量文件变更)
# 在本地执行
rsync -avz --exclude='chroma_db' --exclude='rag/chroma_db' \
--exclude='logs' --exclude='__pycache__' --exclude='frontend' \
--exclude='node_modules' --exclude='.venv' --exclude='.git' \
--exclude='*.pyc' --exclude='.env' \
D:/PythonProject/你的项目文件夹/ root@你的服务器IP:/data/shier_agent/
4.2 服务器上重新构建并启动
cd /data/shier_agent
sudo docker compose down # 停止旧容器
sudo docker compose up -d --build # 重新构建并启动
sudo docker compose logs -f # 查看启动日志
4.3 验证更新
# API 健康检查
curl http://127.0.0.1:8000/health
# Streamlit 页面
curl http://127.0.0.1:8501
常见问题排查
Q1: iptables: No chain/target/match by that name
错误现象:
Error response from daemon: driver failed programming external connectivity
on endpoint learn_agent: iptables failed: iptables --wait -t nat -A DOCKER
-p tcp -d 0/0 --dport 8000 -j DNAT --to-destination 172.18.0.2:8000
! -i br-512396465b1d: iptables: No chain/target/match by that name.
原因分析:
CentOS 7 默认启用 firewalld,与 Docker 的 iptables 规则冲突。
解决方案:
sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo systemctl restart docker
cd /data/shier_agent
sudo docker compose down
sudo docker compose up -d
Q2: Failed to resolve 'dashscope.aliyuncs.com'
错误现象:
{
"detail": "HTTPSConnectionPool(host='dashscope.aliyuncs.com', port=443):
Max retries exceeded with url: /api/v1/services/embeddings/text-embedding/text-embedding
(Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x7f8b3c0a0d90>:
Failed to resolve 'dashscope.aliyuncs.com' ([Errno -3] Temporary failure in name resolution)"))"
}
原因分析:
Docker 容器内 DNS 配置缺失,无法解析阿里云域名。
解决方案:
确认 docker-compose.yml 中包含以下配置:
dns:
- 223.6.6.6
- 8.8.8.8
如没有,补充后重建容器:
cd /data/shier_agent
sudo docker compose down
sudo docker compose up -d --build
Q3: RAG 检索返回空结果
错误现象:
{
"query": "怎么保养扫地机器人",
"documents": [],
"count": 0
}
原因分析:
服务器上 data/ 目录为空,知识库未加载。
解决方案:
参考 第三步 3.3 上传知识库文件并触发重载。
Q4: .env 文件内容乱码或 API 密钥不生效
错误现象:
- API 调用返回 401 Unauthorized
- 日志中显示
ANTHROPIC_API_KEY为空或乱码
原因分析:
在服务器上通过 heredoc 粘贴 .env 内容时,中文字符或特殊符号导致编码损坏。
解决方案:
# 删除损坏的文件
sudo rm -f /data/shier_agent/.env
# 从本地上传正确的 .env
scp D:/PythonProject/你的项目文件夹/.env root@你的服务器IP:/data/shier_agent/.env
# 重启容器使新配置生效
cd /data/shier_agent
sudo docker compose restart
Q5: Docker 构建速度慢
现象:
docker compose build 执行时间超过 30 分钟。
原因分析:
- 国内网络访问 Docker Hub 速度慢
- Python 依赖包下载速度慢
解决方案:
- 确认
/etc/docker/daemon.json中已配置镜像加速 - 耐心等待,首次构建需要下载基础镜像和依赖包
- 如果超过 1 小时仍未完成,检查网络连接
附录
A.1 环境变量说明
| 变量名 | 说明 | 必填 |
|---|---|---|
ANTHROPIC_BASE_URL | 阿里云 DashScope API 地址 | 是 |
ANTHROPIC_API_KEY | DashScope API 密钥 | 是 |
LANGSMITH_API_KEY | LangSmith 追踪密钥 | 否 |
ZHIPU_API_KEY | 智谱 AI API 密钥 | 否 |
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION | Protobuf 实现方式 | 是 |
A.2 常用运维命令
# 查看容器状态
sudo docker ps
# 查看容器日志
sudo docker compose logs -f
# 重启容器
sudo docker compose restart
# 停止容器
sudo docker compose down
# 查看容器资源占用
sudo docker stats learn-agent
# 进入容器内部
sudo docker exec -it learn-agent bash
# 查看 Nginx 日志
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
A.3 性能优化建议
针对 2GB 内存服务器:
- 调整 Uvicorn workers: 保持
--workers 1,避免多进程占用过多内存 - 限制 ChromaDB 缓存: 在
config/chroma.yml中设置合理的chunk_size - 定期清理日志: 设置日志轮转,避免磁盘占满
# 清理 Docker 日志
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"
# 清理应用日志
sudo find /data/shier_agent/logs -name "*.log" -mtime +7 -delete
A.4 安全加固建议
- 修改 SSH 默认端口: 编辑
/etc/ssh/sshd_config,将Port 22改为其他端口 - 禁用 root 远程登录: 设置
PermitRootLogin no - 配置 HTTPS: 使用 Let's Encrypt 申请免费 SSL 证书
- 限制 API 访问频率: 在 FastAPI 中集成
slowapi限流中间件
总结
本文档详细介绍了智扫通机器人在 CentOS 7 + Docker 环境下的完整部署流程,涵盖了从本地准备到服务器部署、验证和更新的全过程。通过遵循本指南,您可以快速搭建一个稳定可靠的生产环境。
如遇到文档中未涵盖的问题,请参考项目 GitHub Issues 或联系技术支持。