AI 搜索服务 Docker 生产部署实战:从上线到稳定运行
AI搜索 Docker部署教程|生产环境实测
本文以“AI搜索”类应用的生产环境部署为核心,演示如何使用 Docker / Docker Compose 快速搭建一套可长期运行、可维护、可备份、可扩展的 AI 搜索服务。
适用场景:企业内部知识检索、私有化 AI 搜索入口、类 Perplexity 搜索问答系统、RAG 检索问答系统、开源 AI Search 项目生产部署。
一、前言:为什么用 Docker 部署 AI 搜索?
AI 搜索和传统搜索最大的区别在于,它不仅返回网页链接或文档列表,还会结合搜索结果、知识库内容、大语言模型能力,生成结构化答案。
一个完整的 AI 搜索服务,通常包含以下组件:
-
前端服务
- 用户输入问题
- 展示搜索结果
- 展示 AI 总结答案
- 支持历史记录、引用来源、会话管理等
-
后端 API 服务
- 接收用户问题
- 调用搜索引擎或知识库
- 调用大语言模型生成答案
- 管理用户、权限、日志等
-
搜索引擎 / 元搜索服务
- 对接 Bing、Google、SearXNG、SerpAPI 等
- 或者对接企业内部文档、数据库、Elasticsearch、向量数据库
-
数据库
- 保存用户信息、会话记录、搜索历史、系统配置等
-
缓存服务
- Redis 常用于缓存搜索结果、会话状态、限流计数等
-
向量数据库,可选
- 如 Milvus、Qdrant、Weaviate、pgvector
- 用于知识库语义检索
-
反向代理
- Nginx、Caddy、Traefik 等
- 负责 HTTPS、域名绑定、负载均衡、安全头等
如果直接在宿主机上手动安装这些组件,后期维护成本会很高。Docker 的优势在于:
- 环境一致,避免“本地能跑,服务器不能跑”
- 部署简单,迁移方便
- 组件隔离,减少依赖冲突
- 便于升级、回滚、备份
- 适合生产环境标准化运维
本文会以一套通用生产环境架构为例,讲解如何从零部署 AI 搜索服务。
二、服务器配置建议
生产环境建议不要使用太低配置的机器。AI 搜索虽然不一定本地运行大模型,但涉及搜索、数据库、缓存、接口转发和页面渲染,资源过低会影响响应速度。
1. 最低配置
| 项目 | 建议 |
|---|---|
| CPU | 2 核 |
| 内存 | 4GB |
| 硬盘 | 40GB SSD |
| 系统 | Ubuntu 22.04 LTS / Debian 12 |
| 带宽 | 5Mbps 以上 |
| Docker | 24.x+ |
| Docker Compose | v2.x |
2. 推荐生产配置
| 项目 | 建议 |
|---|---|
| CPU | 4 核以上 |
| 内存 | 8GB / 16GB |
| 硬盘 | 100GB SSD 以上 |
| 系统 | Ubuntu 22.04 LTS |
| 带宽 | 10Mbps 以上 |
| 数据库 | 独立 volume 持久化 |
| HTTPS | 必须开启 |
| 备份 | 每日自动备份 |
如果你使用本地大模型,例如 Ollama、vLLM、LM Studio 等,则需要额外考虑 GPU、显存、模型大小和推理并发。本文主要以“调用外部 LLM API”的 AI 搜索系统为例,例如 OpenAI API、DeepSeek API、通义千问、智谱、Kimi、Claude 等。
三、整体架构设计
生产环境建议采用如下架构:
用户浏览器
|
| HTTPS
v
Nginx / Caddy 反向代理
|
v
AI Search Web / API 服务
|
|--------> 搜索服务 SearXNG / Search API
|
|--------> LLM API,例如 OpenAI / DeepSeek / Qwen
|
|--------> PostgreSQL 数据库
|
|--------> Redis 缓存
本文示例中的服务包括:
| 服务名 | 作用 |
|---|---|
ai-search |
AI 搜索主服务 |
postgres |
PostgreSQL 数据库 |
redis |
缓存服务 |
searxng |
元搜索引擎,可选 |
nginx |
反向代理和 HTTPS 入口 |
如果你的 AI 搜索项目已经自带 docker-compose.yml,可以参考本文思路进行生产化改造。
四、安装 Docker 和 Docker Compose
以下命令以 Ubuntu 22.04 为例。
1. 更新系统
sudo apt update
sudo apt upgrade -y
2. 安装基础工具
sudo apt install -y ca-certificates curl gnupg lsb-release ufw
3. 安装 Docker
curl -fsSL https://get.docker.com | sudo bash
安装完成后查看版本:
docker version
4. 安装 Docker Compose
新版 Docker 一般自带 Compose 插件:
docker compose version
如果可以正常输出版本号,说明已经安装成功。
5. 设置当前用户使用 Docker
sudo usermod -aG docker $USER
然后重新登录服务器,或者执行:
newgrp docker
五、创建部署目录
建议所有生产项目统一放在 /opt 目录下:
sudo mkdir -p /opt/ai-search
sudo chown -R $USER:$USER /opt/ai-search
cd /opt/ai-search
目录规划如下:
/opt/ai-search
├── docker-compose.yml
├── .env
├── nginx
│ └── ai-search.conf
├── data
│ ├── postgres
│ ├── redis
│ └── searxng
└── backups
创建目录:
mkdir -p nginx data/postgres data/redis data/searxng backups
六、编写环境变量文件
创建 .env 文件:
vim .env
示例内容如下:
# 基础配置
DOMAIN=search.example.com
TZ=Asia/Shanghai
# 应用配置
APP_ENV=production
APP_PORT=3000
APP_URL=https://search.example.com
# 数据库配置
POSTGRES_DB=ai_search
POSTGRES_USER=ai_search_user
POSTGRES_PASSWORD=请替换为强密码
# Redis 配置
REDIS_PASSWORD=请替换为Redis强密码
# LLM API 配置
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-mini
# 搜索配置
SEARCH_PROVIDER=searxng
SEARXNG_URL=http://searxng:8080
# 安全配置
JWT_SECRET=请替换为至少32位随机字符串
ENCRYPTION_KEY=请替换为至少32位随机字符串
生产环境一定不要使用默认密码。
可以使用以下命令生成随机密钥:
openssl rand -hex 32
例如:
JWT_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
七、编写 Docker Compose 文件
创建 docker-compose.yml:
vim docker-compose.yml
示例配置如下:
services:
ai-search:
image: your-ai-search-image:latest
container_name: ai-search
restart: unless-stopped
env_file:
- .env
environment:
NODE_ENV: production
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
SEARXNG_URL: ${SEARXNG_URL}
OPENAI_API_KEY: ${OPENAI_API_KEY}
OPENAI_BASE_URL: ${OPENAI_BASE_URL}
OPENAI_MODEL: ${OPENAI_MODEL}
JWT_SECRET: ${JWT_SECRET}
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
depends_on:
- postgres
- redis
- searxng
networks:
- ai-search-net
expose:
- "3000"
postgres:
image: postgres:16-alpine
container_name: ai-search-postgres
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
TZ: ${TZ}
volumes:
- ./data/postgres:/var/lib/postgresql/data
networks:
- ai-search-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: ai-search-redis
restart: unless-stopped
command: >
redis-server
--requirepass ${REDIS_PASSWORD}
--appendonly yes
--appendfsync everysec
volumes:
- ./data/redis:/data
networks:
- ai-search-net
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 10s
timeout: 5s
retries: 5
searxng:
image: searxng/searxng:latest
container_name: ai-search-searxng
restart: unless-stopped
environment:
- BASE_URL=https://${DOMAIN}/searxng/
- INSTANCE_NAME=AI Search SearXNG
volumes:
- ./data/searxng:/etc/searxng
networks:
- ai-search-net
expose:
- "8080"
nginx:
image: nginx:1.25-alpine
container_name: ai-search-nginx
restart: unless-stopped
depends_on:
- ai-search
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx:/etc/nginx/conf.d
- ./certs:/etc/nginx/certs
- ./logs/nginx:/var/log/nginx
networks:
- ai-search-net
networks:
ai-search-net:
driver: bridge
需要注意的是:
image: your-ai-search-image:latest
这里需要替换成你实际使用的 AI 搜索项目镜像。例如:
image: ghcr.io/xxx/ai-search:latest
或者如果项目需要本地构建,可以改成:
build:
context: .
dockerfile: Dockerfile
八、配置 Nginx 反向代理
创建 Nginx 配置文件:
vim nginx/ai-search.conf
如果你暂时没有证书,可以先使用 HTTP 配置:
server {
listen 80;
server_name search.example.com;
client_max_body_size 20m;
location / {
proxy_pass http://ai-search:3000;
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 300s;
proxy_send_timeout 300s;
}
location /searxng/ {
proxy_pass http://searxng:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
将 search.example.com 替换为你的实际域名。
生产环境建议开启 HTTPS。你可以使用宿主机上的 Certbot,也可以使用 Caddy 自动签发证书。为了简化生产维护,我更推荐 Caddy,但如果公司已有 Nginx 标准化体系,也可以继续使用 Nginx。
九、启动服务
在 /opt/ai-search 目录执行:
docker compose pull
docker compose up -d
查看容器状态:
docker compose ps
查看日志:
docker compose logs -f ai-search
如果看到类似以下输出,说明服务基本启动成功:
Server started on port 3000
Database connected
Redis connected
Search provider initialized
访问:
http://search.example.com
如果已经配置 HTTPS,则访问:
https://search.example.com
十、初始化数据库
不同 AI 搜索项目初始化方式不完全一样。常见方式有以下几种。
1. 自动初始化
有些项目启动时会自动创建表结构,无需手动操作。
只需要观察日志:
docker compose logs -f ai-search
如果没有数据库报错,即可继续使用。
2. 手动执行迁移命令
如果项目使用 Prisma、TypeORM、Django、Rails 等框架,可能需要手动执行迁移。
例如 Node.js 项目:
docker compose exec ai-search npm run migrate
或者:
docker compose exec ai-search npx prisma migrate deploy
如果是 Python 项目:
docker compose exec ai-search python manage.py migrate
执行完成后重启服务:
docker compose restart ai-search
十一、生产环境关键配置
很多 AI 搜索项目在本地环境能跑,但一到生产环境就容易出现超时、接口失败、内存过高、数据库锁表等问题。下面是生产环境实测中比较重要的配置项。
1. 设置重启策略
所有核心服务都建议配置:
restart: unless-stopped
这样服务器重启或容器异常退出后,服务可以自动恢复。
2. 数据必须持久化
数据库和 Redis 数据必须挂载到宿主机目录:
volumes:
- ./data/postgres:/var/lib/postgresql/data
- ./data/redis:/data
否则容器删除后数据会丢失。
3. 不要暴露数据库端口
生产环境不建议这样写:
ports:
- "5432:5432"
如果没有特殊需求,数据库只在 Docker 内部网络访问即可。
4. 配置接口超时时间
AI 搜索通常会调用外部搜索 API 和 LLM API,响应时间比普通接口长。
Nginx 需要配置:
proxy_read_timeout 300s;
proxy_send_timeout 300s;
否则用户提问后,后端还在生成答案,Nginx 已经超时断开连接。
5. 限制上传大小
如果支持文件上传、知识库导入,建议配置:
client_max_body_size 50m;
同时应用层也要配置上传大小限制。
6. 设置日志轮转
Docker 日志如果不限制,长期运行会占满磁盘。
可以在 /etc/docker/daemon.json 中配置:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "5"
}
}
重启 Docker:
sudo systemctl restart docker
十二、配置 HTTPS
生产环境强烈建议启用 HTTPS,尤其是 AI 搜索服务通常包含用户问题、企业资料、聊天记录等敏感数据。
如果使用 Certbot:
sudo apt install -y certbot
申请证书:
sudo certbot certonly --standalone -d search.example.com
证书路径通常为:
/etc/letsencrypt/live/search.example.com/fullchain.pem
/etc/letsencrypt/live/search.example.com/privkey.pem
可以将证书复制到项目目录:
mkdir -p /opt/ai-search/certs
sudo cp /etc/letsencrypt/live/search.example.com/fullchain.pem /opt/ai-search/certs/
sudo cp /etc/letsencrypt/live/search.example.com/privkey.pem /opt/ai-search/certs/
sudo chown -R $USER:$USER /opt/ai-search/certs
然后修改 Nginx 配置:
server {
listen 80;
server_name search.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name search.example.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
client_max_body_size 50m;
location / {
proxy_pass http://ai-search:3000;
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 https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
location /searxng/ {
proxy_pass http://searxng:8080/;
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 容器:
docker compose restart nginx
十三、防火墙配置
服务器只需要开放 SSH、HTTP、HTTPS。
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
查看状态:
sudo ufw status
如果你的 SSH 使用了非 22 端口,请先放行对应端口,避免把自己锁在服务器外。
十四、AI 搜索参数调优
AI 搜索体验好不好,除了部署稳定,还取决于搜索和模型参数。
1. 模型选择
生产环境建议优先选择响应快、价格可控、上下文长度足够的模型。
常见选择:
| 模型类型 | 特点 |
|---|---|
| GPT-4o mini | 速度快,成本较低 |
| DeepSeek Chat | 中文效果好,性价比高 |
| Qwen Plus / Turbo | 国内网络友好 |
| Claude Haiku / Sonnet | 长文本处理优秀 |
| 本地模型 | 数据可控,但机器成本高 |
2. 搜索结果数量
建议初始设置为 5 到 10 条。
搜索结果过少,答案可能不全面;搜索结果过多,会增加 token 消耗和响应时间。
3. 答案生成温度
AI 搜索不是创意写作,建议温度不要太高:
LLM_TEMPERATURE=0.2
这样答案更稳定,幻觉更少。
4. 引用来源
生产环境一定要开启引用来源展示。
用户不仅需要 AI 总结,也需要知道答案来自哪里。
建议配置:
ENABLE_CITATION=true
5. 缓存策略
对于重复查询较多的场景,可以开启搜索缓存:
SEARCH_CACHE_TTL=3600
表示搜索结果缓存 1 小时,能明显降低搜索 API 成本。
十五、数据备份方案
生产环境必须做备份,尤其是数据库。
1. 手动备份 PostgreSQL
docker compose exec postgres pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} > backups/ai_search_$(date +%F).sql
如果命令中的环境变量没有生效,可以直接写实际用户名和数据库名:
docker compose exec postgres pg_dump -U ai_search_user ai_search > backups/ai_search_$(date +%F).sql
2. 恢复数据库
cat backups/ai_search_2025-01-01.sql | docker compose exec -T postgres psql -U ai_search_user ai_search
3. 定时备份
创建脚本:
vim backup.sh
内容如下:
#!/bin/bash
cd /opt/ai-search || exit 1
BACKUP_DIR="/opt/ai-search/backups"
DATE=$(date +%F_%H-%M-%S)
docker compose exec -T postgres pg_dump -U ai_search_user ai_search > "${BACKUP_DIR}/ai_search_${DATE}.sql"
find "${BACKUP_DIR}" -name "ai_search_*.sql" -mtime +14 -delete
授权:
chmod +x backup.sh
添加定时任务:
crontab -e
每天凌晨 3 点备份:
0 3 * * * /opt/ai-search/backup.sh >> /opt/ai-search/backups/backup.log 2>&1
十六、升级与回滚
1. 正常升级
cd /opt/ai-search
docker compose pull
docker compose up -d
升级后观察日志:
docker compose logs -f ai-search
2. 升级前备份
升级前一定要备份数据库:
./backup.sh
如果项目有数据库迁移,升级后可能无法直接降级,所以务必保留旧镜像版本。
3. 固定镜像版本
生产环境不建议长期使用:
image: your-ai-search-image:latest
建议固定版本:
image: your-ai-search-image:v1.2.3
这样可以避免项目自动拉取最新镜像后出现不兼容问题。
4. 回滚方式
如果升级失败,可以修改镜像版本为旧版本:
image: your-ai-search-image:v1.2.2
然后执行:
docker compose up -d
如果数据库结构已经被新版本迁移,可能还需要恢复备份。
十七、常见问题排查
1. 页面打不开
检查容器是否正常:
docker compose ps
检查 Nginx 日志:
docker compose logs -f nginx
检查主服务日志:
docker compose logs -f ai-search
常见原因:
- 域名没有解析到服务器
- 防火墙没有开放 80 / 443
- Nginx 配置错误
- AI Search 服务没有启动
- 容器网络不通
2. 数据库连接失败
查看 PostgreSQL 状态:
docker compose logs -f postgres
常见原因:
POSTGRES_PASSWORD和DATABASE_URL不一致- 数据库容器还没初始化完成
- 数据目录权限异常
- 旧数据目录中已有不同用户配置
如果是首次部署出错,可以清理数据目录后重新初始化:
docker compose down
rm -rf data/postgres/*
docker compose up -d
注意:这会删除数据库数据,只适合首次部署阶段。
3. Redis 认证失败
检查 Redis 密码:
docker compose logs -f redis
确认 REDIS_URL 中的密码和 REDIS_PASSWORD 一致:
REDIS_URL=redis://:你的密码@redis:6379/0
4. AI 回答很慢
可能原因:
- LLM API 响应慢
- 搜索服务响应慢
- 搜索结果数量太多
- 模型上下文过长
- 网络到模型服务不稳定
优化建议:
- 减少搜索结果数量
- 使用更快模型
- 开启缓存
- 增加接口超时时间
- 使用国内可访问性更好的模型服务
5. AI 答案不准确
AI 搜索的准确性很大程度取决于搜索结果质量。
建议:
- 开启引用来源
- 优化搜索 query 改写
- 限制模型必须基于搜索结果回答
- 对低可信来源降权
- 企业场景优先接入内部知识库
- 对敏感问题增加人工审核或免责声明
十八、生产环境安全建议
AI 搜索入口一旦暴露到公网,就必须重视安全。
1. 开启登录认证
如果是企业内部使用,建议开启账号体系,不要匿名开放。
2. 增加访问限流
可以在 Nginx 中增加基础限流:
limit_req_zone $binary_remote_addr zone=ai_search_limit:10m rate=5r/s;
在 server 或 location 中使用:
limit_req zone=ai_search_limit burst=20 nodelay;
3. 隐藏管理入口
如果项目有后台管理路径,例如 /admin,建议:
- 增加管理员权限校验
- 限制 IP 访问
- 开启二次验证
- 不要使用弱密码
4. API Key 不要写进前端
LLM API Key 必须只保存在后端环境变量中。
不要把 API Key 写在前端代码、浏览器 localStorage 或公开配置文件中。
5. 定期更新镜像
至少每月检查一次基础镜像和应用镜像安全更新。
docker compose pull
docker compose up -d
十九、生产实测经验总结
经过实际部署和运行,AI 搜索生产环境最容易踩坑的地方主要有以下几个。
1. 超时问题比性能问题更常见
AI 搜索链路较长:
用户提问 -> 搜索 -> 抓取内容 -> 整理上下文 -> 调用模型 -> 流式返回
任何一个环节慢,都会导致整体变慢。
所以 Nginx、后端服务、模型请求都要合理设置超时时间。
2. 日志一定要控制大小
Docker 默认日志长期运行可能占用几十 GB。
生产服务器磁盘满了以后,数据库和容器都会异常。
3. 数据库备份不能省
很多人以为 AI 搜索只是一个工具,数据丢了无所谓。
但实际运行一段时间后,里面会积累大量用户会话、知识库配置、系统设置和审计信息。数据库备份必须自动化。
4. 模型成本需要监控
如果开放给多人使用,LLM API 成本可能增长很快。
建议增加:
- 用户级调用次数限制
- 单次问题 token 限制
- 缓存策略
- 模型分级策略
- 日志审计
例如普通问题使用低成本模型,复杂问题再切换高质量模型。
5. 不建议裸奔开放公网
如果没有登录认证和限流,AI 搜索很容易被滥用。
轻则 API 费用暴涨,重则服务被刷爆。
二十、最终检查清单
上线前建议逐项检查:
- [ ] 域名已正确解析
- [ ] HTTPS 已开启
- [ ] Docker Compose 服务全部正常
- [ ] 数据库已持久化
- [ ] Redis 已设置密码
- [ ] LLM API Key 未暴露到前端
- [ ] Nginx 超时时间已调大
- [ ] Docker 日志轮转已配置
- [ ] 防火墙只开放必要端口
- [ ] 已配置数据库自动备份
- [ ] 已开启登录认证或访问控制
- [ ] 已测试升级和回滚流程
- [ ] 已设置监控或至少保留日志
结语
使用 Docker 部署 AI 搜索并不复杂,真正的难点在于生产环境的稳定性、安全性和可维护性。一个能在本地运行的 AI 搜索项目,距离生产可用还需要补齐 HTTPS、数据库持久化、备份、限流、日志轮转、权限控制、模型成本控制等环节。
如果只是个人体验,可以用最简单的 Docker Compose 快速启动;如果是企业内部或公网服务,建议按照本文的生产环境方案进行部署。这样后续无论是升级、迁移、排障还是扩容,都会更加可控。
简而言之,AI 搜索部署的核心原则是:
容器化运行、数据持久化、入口 HTTPS、密钥后端化、日志可控、备份自动化、访问有限流。
只要把这些基础工作做好,一套 AI 搜索服务就可以比较稳定地长期运行。