LocalGPT 容器化部署完全指南:基于 Docker 与本地 Ollama 的私有化 RAG 系统搭建
【免费下载链接】localGPTChat with your documents on your local device using GPT models. No data leaves your device and 100% private.项目地址: https://gitcode.com/GitHub_Trending/lo/localGPT
导读
本指南以仓库根目录的 DOCKER_README.md 为核心骨架,系统讲解如何在 Docker 容器中运行 LocalGPT——一个完全本地化的"文档对话"系统:前端 Next.js 界面、后端会话网关与 RAG API 检索服务三者容器化,而大模型推理交给宿主机上的 Ollama,实现数据不出本机、100% 私有。读完本文你将掌握:5 分钟快速启动流程、三容器 + 本地 Ollama 的架构与数据卷设计、docker.env与模型配置的每一项参数含义、./start-docker.sh全部子命令及原生 docker compose 等价操作、容器级调试与常见故障的排查套路,以及判断部署是否成功的验收标准。
一、快速开始:5 分钟跑通完整链路
按照官方推荐的完整流程,在满足前置条件的机器上按顺序执行即可:
# 1. 安装本地 Ollama curl -fsSL https://ollama.ai/install.sh | sh # 2. 启动 Ollama 服务端 ollama serve # 3. 在另一个终端拉取所需模型 ollama pull qwen3:0.6b ollama pull qwen3:8b # 4. 克隆仓库并启动 LocalGPT git clone https://github.com/your-org/rag-system.git cd rag-system ./start-docker.sh # 5. 访问应用 open http://localhost:3000从源码角度补充说明几点执行细节:
./start-docker.sh默认走local分支:脚本会先调用check_local_ollama(),通过curl -s http://localhost:11434/api/tags探测宿主机 Ollama 是否存活(见 start-docker.sh);若未检测到本地 Ollama,脚本会交互式询问是否改用容器化 Ollama(--profile with-ollama),回答y则自动切换,否则取消启动。- 为什么推荐本地 Ollama:原文档给出的理由是四点——直接访问 GPU 性能更好、少一个容器部署更简单、模型管理更方便、连接更可靠。此外从架构上看,把最吃显存的推理进程留在宿主机,也便于用
ollama list、ollama ps等原生工具管理模型生命周期。 - 若在 Linux 上执行
./start-docker.sh探测失败,可先手动确认curl http://localhost:11434/api/tags是否返回 JSON,再检查下文的环境变量小节中的网关地址配置。
启动成功后各服务端口约定如下(与原文档、start-docker.sh 的提示输出一致):
| 服务 | 地址 | 说明 |
|---|---|---|
| 前端 | http://localhost:3000 | Next.js Web 界面 |
| 后端 | http://localhost:8000 | 会话管理、聊天历史、API 网关 |
| RAG API | http://localhost:8001 | 文档索引、检索、AI 处理 |
| Ollama | http://localhost:11434 | 宿主机本地推理服务 |
二、前置条件与资源规划
原文档列出的硬性要求:
- Docker Desktop已安装并运行(macOS / Windows;Linux 则需 Docker Engine 服务,见 DOCKER_TROUBLESHOOTING.md 中
sudo systemctl status docker的排查方式); - Ollama 本机安装(即使使用 Docker 部署也建议保留,以获得最佳性能);
- 8GB+ 内存(运行更大模型建议 16GB);
- 10GB+ 可用磁盘空间(需容纳 Docker 镜像、模型权重、向量数据库与上传文档)。
结合仓库的镜像定义,可将资源估算得更精确:
- 前端镜像基于
node:18-alpine,约占用数百 MB(见 Dockerfile.frontend); - 后端与 RAG API 镜像均基于
python:3.11-slim,并安装requirements-docker.txt中的依赖(见 Dockerfile.backend、Dockerfile.rag-api),其中包含 torch、transformers、lancedb 等重量级 Python 包,构建阶段较耗时,属正常现象; - 模型权重由 Ollama 管理(
qwen3:0.6b约 650MB,qwen3:8b约 4.7GB,参考 Documentation/docker_usage.md 的说明),不进入 Docker 镜像。
三、架构总览:三容器 + 本地 Ollama
原文档给出如下架构图,三个应用容器横向串联,RAG API 向下调用宿主机 Ollama:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Frontend │────│ Backend │────│ RAG API │ │ (Container) │ │ (Container) │ │ (Container) │ │ Port: 3000 │ │ Port: 8000 │ │ Port: 8001 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ API calls ▼ ┌─────────────────┐ │ Ollama │ │ (Local/Host) │ │ Port: 11434 │ └─────────────────┘3.1 容器职责与启动细节
原文档对三个容器的定位、镜像、端口与健康检查如下表(内存占用为文档给出的经验值,实际随负载浮动):
| 容器 | 镜像基础 | 端口 | 职责 | 健康检查 | 内存参考 |
|---|---|---|---|---|---|
| rag-frontend | Node.js 18 定制构建 | 3000 | Next.js Web 界面 | HTTP GET/ | ~500MB |
| rag-backend | Python 3.11 定制构建 | 8000 | 会话管理、聊天历史、API 网关 | HTTP GET/health | ~300MB |
| rag-api | Python 3.11 定制构建 | 8001 | 文档索引、检索、AI 处理 | HTTP GET/models | ~2GB(随模型使用波动) |
从 docker-compose.yml 可以看到更完整的编排细节:
- 启动顺序通过
depends_on的condition: service_healthy保证:backend 等待 rag-api 健康、frontend 等待 backend 健康,形成严格的依赖链,避免出现"前端已就绪但后端还在初始化"的窗口期; - 所有容器均配置健康检查(
healthcheck每 30s 探测一次、超时 10s、连续 3 次失败标记为 unhealthy)与restart: unless-stopped自动重启策略; - 共享网络
rag-network(bridge 驱动):backend 通过服务名rag-api:8001访问 RAG API(对应环境变量RAG_API_URL=http://rag-api:8001),这是 compose 内置 DNS 的典型用法,无需依赖固定 IP。
3.2 RAG API 内部初始化逻辑
RAG API 容器启动命令为python -m rag_system.api_server(见 Dockerfile.rag-api)。结合 rag_system/api_server.py 的源码,其初始化流程是:
- 模块加载时即创建全局
ChatDatabase()连接(数据库路径由DATABASE_PATH环境变量决定,容器内默认为/app/backend/chat_data.db); - 依据
RAG_CONFIG_MODE(默认default)通过get_agent()与get_indexing_pipeline()构建 RAG Agent 与索引流水线; - 打印
🧠 Initializing RAG Agent with MAXIMUM ACCURACY...并一次性加载模型,模型只在服务启动时加载一次,后续请求复用全局单例,避免每次请求重复加载权重导致响应变慢——这也是为什么文档提醒"RAG API 首次启动可能较慢"。
四、数据持久化:Volume Mounts 与共享存储
原文档定义的四类持久化数据:
| 宿主机路径 | 容器内路径 | 用途 |
|---|---|---|
./lancedb/ | /app/lancedb | 向量数据库存储(LanceDB) |
./index_store/ | /app/index_store | 文档索引与元数据 |
./shared_uploads/ | /app/shared_uploads | 上传的文档文件 |
./backend/chat_data.db | /app/backend/chat_data.db | SQLite 聊天历史数据库 |
"共享"的语义:通过 bind mount,rag-api 与 backend 都能访问shared_uploads;rag-api 独占lancedb与index_store;backend 独占chat_data.db(但 docker-compose.local-ollama.yml 中对数据库做了精确到单文件的挂载)。宿主机直接修改这些目录即可完成备份或清理,无需进入容器。
重要区分:docker.env中声明的DATABASE_PATH=/app/backend/chat_data.db、LANCEDB_PATH=/app/lancedb、UPLOADS_PATH=/app/shared_uploads是容器内路径,服务于应用代码;而 compose 文件中的./lancedb:/app/lancedb这类映射是宿主机 ↔ 容器的桥接。两者配合才构成完整的数据通路。
五、配置详解:docker.env 与模型配置
5.1 环境变量文件 docker.env
仓库根目录的 docker.env 是官方默认配置,原文档将其归纳为三组:
# Ollama Configuration OLLAMA_HOST=http://host.docker.internal:11434 # Service Configuration NODE_ENV=production RAG_API_URL=http://rag-api:8001 NEXT_PUBLIC_API_URL=http://localhost:8000 # Database Paths (inside containers) DATABASE_PATH=/app/backend/chat_data.db LANCEDB_PATH=/app/lancedb UPLOADS_PATH=/app/shared_uploads结合源码与当前仓库实际文件,这里需要澄清一个关键差异(文档版本演进带来的地址变化):
- docker-compose.yml 中 rag-api 的
OLLAMA_HOST默认值为${OLLAMA_HOST:-http://host.docker.internal:11434},即默认使用host.docker.internal(macOS/Windows 上由 Docker Desktop 提供,指向宿主机); - 但当前仓库的 docker.env 实际写入的是
OLLAMA_HOST=http://172.18.0.1:11434,文件注释明确说明:"Using Docker gateway IP instead of host.docker.internal for Linux compatibility"(Linux 上host.docker.internal不可用时,改用 Docker 默认 bridge 网段172.18.0.1指向宿主机); - backend 容器在 docker-compose.yml 中的默认值则是
${OLLAMA_HOST:-http://172.18.0.1:11434}。
实操建议:如果你的 Docker 网络网段不是默认的172.18.0.1,可在docker compose exec rag-api后执行route -n或ip route查看网关 IP,并同步修改docker.env;host.docker.internal在 Linux 上也可通过--add-host=host.docker.internal:host-gateway方式启用(当前仓库未内置该配置)。其余三个服务级变量含义:
NODE_ENV=production:以生产模式运行 Node/Python 服务;RAG_API_URL=http://rag-api:8001:backend 通过 compose 内部 DNS 服务名访问 RAG API;NEXT_PUBLIC_API_URL=http://localhost:8000:浏览器端发起请求时访问的 backend 地址(必须是宿主机可达地址)。
5.2 模型配置
原文档默认模型组合如下:
| 用途 | 模型 | 说明 |
|---|---|---|
| Embedding(向量化) | Qwen/Qwen3-Embedding-0.6B | 1024 维向量 |
| Generation(生成) | qwen3:0.6b(快) /qwen3:8b(高质量) | 由 Ollama 管理 |
| Reranking(重排序) | 内置交叉编码器(cross-encoder) | 无需额外模型 |
补充说明:从 rag_system/api_server.py 的_apply_index_embedding_model实现可以看到,每个索引创建时会把embedding_model写入索引元数据,检索时会动态将 retrieval pipeline 的 embedding 模型切换为与该索引一致的模型,从而保证"索引时用什么模型向量化,检索时就用什么模型召回",这是多模型混用场景下保证召回质量的关键机制。
切换生成模型只需一条命令,无需改容器:
ollama pull qwen3:0.6b # 追求响应速度 ollama pull qwen3:8b # 追求回答质量六、管理命令:一键脚本与原生 docker compose
6.1 ./start-docker.sh 一键脚本
原文档列出的命令及其等价逻辑(均已在 start-docker.sh 中实现):
# 启动全部服务(默认 local 模式,先探测本地 Ollama) ./start-docker.sh # 停止全部服务 ./start-docker.sh stop # 重启服务 ./start-docker.sh stop && ./start-docker.sh # 查看状态 ./start-docker.sh status # 查看实时日志 ./start-docker.sh logs脚本还支持两个容易被忽略的模式参数($0 [option],默认local):
./start-docker.sh container:改用容器化 Ollama,执行docker compose --profile with-ollama up --build -d,并设置OLLAMA_HOST=http://ollama:11434。此时会额外拉起 docker-compose.yml 中定义的ollama服务(镜像ollama/ollama:latest,容器名rag-ollama,数据卷ollama_data持久化模型权重);./start-docker.sh status/logs/help:分别对应docker compose ps、按需选择--profile with-ollama logs -f或docker compose logs -f、打印用法帮助。
值得注意的是,脚本的stop分支会同时执行docker compose down与docker compose --profile with-ollama down(后者失败被忽略),确保无论以哪种模式启动都能完整清理。
6.2 原生 docker compose 命令
不依赖脚本、完全手动控制的等价操作:
# 启动(读取 docker.env) docker compose --env-file docker.env up --build -d # 停止 docker compose down # 重建指定服务 docker compose build --no-cache rag-api docker compose up -d rag-api # 查看状态与日志 docker compose ps docker compose logs -f docker compose logs -f rag-api docker compose logs -f backend docker compose logs -f frontend6.3 四端点健康检查
部署后建议立即执行原文档给出的全套健康检查:
curl -f http://localhost:3000 && echo "✅ Frontend OK" curl -f http://localhost:8000/health && echo "✅ Backend OK" curl -f http://localhost:8001/models && echo "✅ RAG API OK" curl -f http://localhost:11434/api/tags && echo "✅ Ollama OK"期望输出为四行全绿(✅ ... OK)。若./start-docker.sh status显示某容器unhealthy,可直接用docker inspect rag-api --format='{{.State.Health.Status}}'查看健康状态详情(见 DOCKER_TROUBLESHOOTING.md)。
七、容器内调试:进 shell、验初始化、查资源
7.1 进入容器
# RAG API 容器(大部分调试发生在这里) docker compose exec rag-api bash # 后端容器 docker compose exec backend bash # 前端容器(alpine 镜像,用 sh) docker compose exec frontend sh7.2 关键调试命令
原文档提供的四类验证命令,逐条说明其验证目标:
# ① 验证 RAG 系统能否初始化(验证 get_agent 链路与模型加载) docker compose exec rag-api python -c " from rag_system.main import get_agent agent = get_agent('default') print('✅ RAG System OK') " # ② 从容器内验证到宿主机 Ollama 的连通性(验证 OLLAMA_HOST 配置) docker compose exec rag-api curl http://host.docker.internal:11434/api/tags # ③ 检查容器内的 Ollama 相关环境变量(确认 docker.env 是否生效) docker compose exec rag-api env | grep OLLAMA # ④ 查看关键 Python 依赖是否装齐(torch/transformers/lancedb) docker compose exec rag-api pip list | grep -E "(torch|transformers|lancedb)"其中第②条是排查"RAG API 连不上 Ollama"最直接的证据:若在容器内curl宿主机 11434 失败,而宿主机本机访问成功,问题几乎必然出在OLLAMA_HOST地址选择(host.docker.internalvs172.18.0.1)或防火墙上。
7.3 资源监控
# 实时监控容器资源 docker stats # 磁盘占用总览 docker system df df -h ./lancedb ./shared_uploads # 按服务查看内存 docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}"八、故障排查手册
8.1 容器无法启动
# 先看对应服务日志定位具体错误 docker compose logs [service-name] # 端口占用排查(3000/8000/8001 同时检查) lsof -i :3000 -i :8000 -i :8001 # 彻底重建 ./start-docker.sh stop docker system prune -f ./start-docker.sh若日志中出现bind: address already in use,说明端口被本机进程占用,可用pkill -f "npm run dev"、pkill -f "server.py"、pkill -f "api_server"清理非 Docker 的本地开发进程,或用sudo kill -9 $(lsof -t -i:3000)按端口强杀(详见 DOCKER_TROUBLESHOOTING.md)。
8.2 连不上 Ollama
# ① 宿主机侧确认 Ollama 存活 curl http://localhost:11434/api/tags # ② 重启 Ollama pkill ollama ollama serve # ③ 容器侧再测 docker compose exec rag-api curl http://host.docker.internal:11434/api/tags若第③步失败而第①步成功,按当前仓库的 docker.env 实践,可将OLLAMA_HOST改为http://172.18.0.1:11434(Linux 网关地址)后./start-docker.sh stop && ./start-docker.sh重启生效。
8.3 内存不足
# 查看当前占用 docker stats --no-stream free -h # 宿主机视角 # 调大 Docker 内存配额 # Docker Desktop → Settings → Resources → Memory → 8GB+ # 换用更小的模型 ollama pull qwen3:0.6b # 替代 qwen3:8b8.4 前端构建失败
# 无缓存重建前端 docker compose build --no-cache frontend docker compose up -d frontend # 查看前端日志 docker compose logs frontend8.5 数据库 / 存储权限问题
# 检查文件权限 ls -la backend/chat_data.db ls -la lancedb/ # 修复权限 chmod 664 backend/chat_data.db chmod -R 755 lancedb/ shared_uploads/ # 容器内验证 SQLite 可读 docker compose exec backend sqlite3 /app/backend/chat_data.db ".tables"若数据库文件缺失,可按 DOCKER_TROUBLESHOOTING.md 提供的方式初始化:
docker compose exec backend python -c " from backend.database import ChatDatabase db = ChatDatabase() db.init_database() print('Database initialized') "8.6 性能优化
- 响应慢:改用
qwen3:0.6b;提高 Docker 内存配额;数据库与向量存储置于 SSD;用docker stats持续观察瓶颈; - 内存占用高:在配置中调小批处理大小(batch size);换更小的 embedding 模型;
docker system prune清理无用资源。
8.7 完全重置(破坏性操作,谨慎执行)
# 停止并清理所有容器、镜像、卷 ./start-docker.sh stop docker system prune -a --volumes # 清空本地数据(⚠️ 将删除全部文档与聊天历史) rm -rf lancedb/* shared_uploads/* backend/chat_data.db # 重新构建启动 ./start-docker.sh如果只想重置部分数据,可选择性删除:仅重置聊天记录删backend/chat_data.db,仅重置向量库删lancedb/*,仅重置上传文档删shared_uploads/*(见 DOCKER_TROUBLESHOOTING.md 的 Selective Reset 一节)。
九、成功标准与性能基线
9.1 部署成功的验收清单
原文档给出的判定标准,全部满足即视为部署成功:
- ✅
./start-docker.sh status显示所有容器 healthy; - ✅ 上文四个端点的健康检查全部通过;
- ✅ 可访问 http://localhost:3000;
- ✅ 能上传文档并创建索引;
- ✅ 能与文档进行对话;
- ✅ 容器日志无报错。
9.2 性能基线参考
原文档给出的两组经验基线(在当前仓库硬件未标定的情况下,作为参考阈值而非承诺指标):
| 指标 | Good(良好) | Optimal(最优) |
|---|---|---|
| 容器启动时间 | < 2 分钟 | < 1 分钟 |
| 索引创建速度 | < 2 分钟 / 100MB 文档 | < 1 分钟 / 100MB 文档 |
| 查询响应时间 | < 30 秒 | < 10 秒 |
| 容器总内存占用 | < 4GB | < 2GB |
十、进阶:容器化 Ollama、独立镜像测试与替代部署
10.1 容器化 Ollama(可选)
若宿主机不便安装 Ollama,可通过 profile 方式在容器中运行:
./start-docker.sh container # 等价于: docker compose --profile with-ollama up --build -d此时rag-ollama容器监听 11434,模型权重存入命名卷ollama_data,OLLAMA_HOST需指向http://ollama:11434(docker.env 中已预留注释掉的备选配置)。注意该模式会牺牲 GPU 直通效率,文档仍推荐本地 Ollama 作为首选。
10.2 单容器独立测试
先单独构建并运行 RAG API 容器,验证镜像本身可用(见 DOCKER_TROUBLESHOOTING.md):
docker build -f Dockerfile.rag-api -t test-rag-api . docker run --rm -p 8001:8001 -e OLLAMA_HOST=http://host.docker.internal:11434 test-rag-api & sleep 30 curl http://localhost:8001/models10.3 替代部署路径
- 纯本地开发(不用 Docker):
python run_system.py(见仓库根目录 run_system.py); - 混合模式:RAG API 入容器、后端与前端直接跑:
docker compose up -d rag-api后分别执行python backend/server.py与npm run dev; - 非 Docker 部署的完整说明见根目录 README.md。
十一、更多资料
- 深度排障手册:DOCKER_TROUBLESHOOTING.md(Docker daemon 重启、网络调试、日志分析、自动化健康测试脚本
test-docker-health.sh等) - Docker 使用全流程:Documentation/docker_usage.md(开发工作流、日志管理、数据备份、Swarm 扩展、镜像安全扫描
docker scout cves) - 系统架构:Documentation/architecture_overview.md
- Docker Compose 编排文件:docker-compose.yml、docker-compose.local-ollama.yml
- 镜像定义:Dockerfile.frontend、Dockerfile.backend、Dockerfile.rag-api
提醒:本仓库为只读研究环境,上述命令中的启动、停止、构建、重置等操作请在你的实际部署机器上执行。
【免费下载链接】localGPTChat with your documents on your local device using GPT models. No data leaves your device and 100% private.项目地址: https://gitcode.com/GitHub_Trending/lo/localGPT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考