使用 Docker Compose 部署私有化 LobeChat 服务
在如今 AI 工具快速普及的背景下,越来越多团队开始关注如何构建一个安全、可控且可定制的内部智能助手。市面上虽然不乏优秀的聊天界面产品,但真正能兼顾美观、功能与数据自主权的开源方案并不多见。LobeChat 正是在这一需求下脱颖而出——它不仅拥有媲美 ChatGPT 的现代 UI 体验,还支持接入 OpenAI、Gemini、本地 Ollama 模型等多种大语言模型,并具备插件系统、角色预设、文件上传和语音交互等完整能力。
更关键的是,LobeChat 完全开源,允许我们将其部署在私有服务器上,实现数据不出内网的安全闭环。本文将带你从零开始,使用Docker Compose在一台 Linux 服务器上完成 LobeChat 的全栈私有化部署,涵盖数据库、认证服务、对象存储与反向代理配置,最终搭建出一个稳定可用的企业级 AI 聊天门户。
环境准备:打好基础才能跑得更远
任何一次成功的部署,都始于扎实的前期准备。我们需要先确保服务器环境满足基本要求。
基础设施条件
- 一台运行 Linux 的云服务器(推荐 Ubuntu 20.04+ 或 CentOS 7+)
- 已安装 Docker 和 Docker Compose
可通过以下命令验证:bash docker --version docker-compose --version - 至少 2GB 内存(建议 4GB 及以上以保证流畅运行)
资源紧张时,可以考虑关闭 MinIO 自建存储,改用外部 S3 兼容服务,从而降低内存占用。
域名与 HTTPS 加密
为了实现安全访问,必须为服务配置有效的域名和 SSL 证书。以下是核心域名规划:
| 域名 | 用途 |
|---|---|
chat.yourdomain.com | LobeChat 主应用入口 |
auth-api.yourdomain.com | 认证服务 API 接口(Logto) |
auth-ui.yourdomain.com | 认证管理后台 |
⚠️ 若你选择自建 MinIO,则还需额外配置:
-s3-api.yourdomain.com(API 接入点)
-s3-ui.yourdomain.com(Web 控制台)
SSL 证书建议使用 Let’s Encrypt 免费签发,或通过阿里云/腾讯云等平台获取。证书文件应包含.pem(公钥)和.key(私钥)两个部分。
对象存储选型
LobeChat 支持图片、文档等富媒体内容上传,这些非结构化数据需要可靠的存储后端。你可以选择:
-自建 MinIO:适合追求完全控制权的用户,本文采用此方案
-第三方云存储:如 AWS S3、阿里云 OSS、腾讯云 COS,省去运维成本
若选用 MinIO,请提前规划好持久化路径和权限策略。
部署流程:一步步构建你的 AI 助手底座
第一步:DNS 解析设置
登录你的 DNS 提供商控制台(如 Cloudflare、阿里云 DNS),添加如下 A 记录:
chat.yourdomain.com → 123.45.67.89 auth-api.yourdomain.com → 123.45.67.89 auth-ui.yourdomain.com → 123.45.67.89等待 DNS 生效后继续操作。可通过ping或dig命令测试解析是否成功。
第二步:创建项目目录并放置证书
mkdir -p ~/lobechat/{ssl,data,s3_data}将所有 SSL 证书放入~/lobechat/ssl目录,命名规范如下:
ssl/ ├── chat.yourdomain.com.pem ├── chat.yourdomain.com.key ├── auth-api.yourdomain.com.pem ├── auth-api.yourdomain.com.key ├── auth-ui.yourdomain.com.pem └── auth-ui.yourdomain.com.key敏感密钥需限制访问权限:
chmod 600 ~/lobechat/ssl/*.key这一步看似简单,却是避免“证书加载失败”类问题的关键。
第三步:编写docker-compose.yml
这是整个部署的核心编排文件,定义了所有服务及其依赖关系。
# docker-compose.yml version: "3.9" services: nginx: image: nginx:alpine container_name: lobe-nginx ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./ssl:/etc/nginx/ssl:ro depends_on: - lobe - logto - minio restart: always postgresql: image: pgvector/pgvector:pg16 container_name: lobe-postgres volumes: - ./data:/var/lib/postgresql/data environment: POSTGRES_DB: lobe POSTGRES_PASSWORD: secure_postgres_password_2025 healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 restart: always minio: image: minio/minio container_name: lobe-minio volumes: - ./s3_data:/data environment: MINIO_ROOT_USER: admin MINIO_ROOT_PASSWORD: minioadmin12345 MINIO_DOMAIN: s3-api.yourdomain.com ports: - "9000:9000" - "9001:9001" command: server /data --address ":9000" --console-address ":9001" restart: always logto: image: logto/io:latest container_name: lobe-logto depends_on: postgresql: condition: service_healthy environment: DB_URL: postgresql://postgres:secure_postgres_password_2025@postgresql:5432/logto ENDPOINT: https://auth-api.yourdomain.com ADMIN_ENDPOINT: https://auth-ui.yourdomain.com TRUST_PROXY_HEADER: "1" entrypoint: ["sh", "-c", "npx logto db seed && exec npx logto dev"] restart: always lobe: image: lobehub/lobe-chat:latest container_name: lobe-chat depends_on: postgresql: condition: service_healthy logto: condition: service_started minio: condition: service_started env_file: - .env restart: always volumes: data: driver: local s3_data: driver: local✅注意:请替换所有
yourdomain.com为实际使用的域名。
这里有几个值得强调的设计点:
- 使用pgvector/pgvector:pg16镜像,未来可直接支持向量嵌入检索。
-logto服务通过entrypoint自动执行数据库初始化脚本,减少手动干预。
-depends_on + condition实现了合理的启动顺序控制,避免因依赖未就绪导致的服务崩溃。
第四步:配置.env环境变量
创建~/lobechat/.env文件:
# .env # 必填:前端应用 URL,用于 tRPC 和鉴权回调 APP_URL=https://chat.yourdomain.com # 数据库加密密钥(生成方式见下方说明) KEY_VAULTS_SECRET=YOUR_GENERATED_32BYTE_BASE64_KEY # PostgreSQL 连接字符串 DATABASE_URL=postgresql://postgres:secure_postgres_password_2025@postgresql:5432/lobe # NextAuth 鉴权配置 NEXTAUTH_SECRET=ANOTHER_32BYTE_RANDOM_BASE64_STRING NEXT_AUTH_SSO_PROVIDERS=logto NEXTAUTH_URL=https://chat.yourdomain.com/api/auth # Logto 认证服务参数(待配置后填入) LOGTO_CLIENT_ID= LOGTO_CLIENT_SECRET= LOGTO_ISSUER=https://auth-api.yourdomain.com/oidc # S3 存储配置(MinIO) S3_ACCESS_KEY_ID=admin S3_SECRET_ACCESS_KEY=minioadmin12345 S3_ENDPOINT=https://s3-api.yourdomain.com S3_BUCKET=lobe-files S3_PUBLIC_DOMAIN=https://s3-api.yourdomain.com S3_ENABLE_PATH_STYLE=1 # 可选:启用 OpenAI 模型支持 # OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # OPENAI_PROXY_URL=https://api.openai.com/v1 # 其他基础配置(按需开启) # LOBE_DEFAULT_MODEL=gpt-3.5-turbo # LOBE_LANG=en-US密钥生成技巧
强烈建议使用 OpenSSL 生成高强度随机密钥:
openssl rand -base64 32分别用于KEY_VAULTS_SECRET和NEXTAUTH_SECRET。这两个字段一旦设定不应随意更改,否则可能导致已有会话无法解密。
第五步:配置 Nginx 反向代理
创建~/lobechat/nginx.conf:
events { worker_connections 1024; } http { upstream lobe { server lobe:3210; } upstream logto_api { server logto:3001; } upstream logto_ui { server logto:3002; } upstream minio_api { server minio:9000; } upstream minio_console { server minio:9001; } # —— LobeChat 主站 —— server { listen 80; server_name chat.yourdomain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name chat.yourdomain.com; ssl_certificate /etc/nginx/ssl/chat.yourdomain.com.pem; ssl_certificate_key /etc/nginx/ssl/chat.yourdomain.com.key; location / { proxy_pass http://lobe; 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_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } # —— Logto API —— server { listen 80; server_name auth-api.yourdomain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name auth-api.yourdomain.com; ssl_certificate /etc/nginx/ssl/auth-api.yourdomain.com.pem; ssl_certificate_key /etc/nginx/ssl/auth-api.yourdomain.com.key; location / { proxy_pass http://logto_api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_xforwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } # —— Logto UI —— server { listen 80; server_name auth-ui.yourdomain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name auth-ui.yourdomain.com; ssl_certificate /etc/nginx/ssl/auth-ui.yourdomain.com.pem; ssl_certificate_key /etc/nginx/ssl/auth-ui.yourdomain.com.key; location / { proxy_pass http://logto_ui; 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; } } # —— MinIO API —— server { listen 80; server_name s3-api.yourdomain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name s3-api.yourdomain.com; ssl_certificate /etc/nginx/ssl/s3-api.yourdomain.com.pem; ssl_certificate_key /etc/nginx/ssl/s3-api.yourdomain.com.key; location / { proxy_pass http://minio_api; proxy_set_header Host $http_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; } client_max_body_size 200M; } # —— MinIO Console —— server { listen 80; server_name s3-ui.yourdomain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name s3-ui.yourdomain.com; ssl_certificate /etc/nginx/ssl/s3-ui.yourdomain.com.pem; ssl_certificate_key /etc/nginx/ssl/s3-ui.yourdomain.com.key; location / { proxy_pass http://minio_console; proxy_set_header Host $http_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; } } # 全局最大上传限制 client_max_body_size 200M; }这个配置实现了多域名分流、HTTPS 强制跳转、WebSocket 支持以及大文件上传处理,是整套架构稳定运行的“交通指挥官”。
第六步:MinIO 权限策略配置
创建minio-bucket-policy.json:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": ["*"] }, "Action": ["s3:GetBucketLocation"], "Resource": "arn:aws:s3:::lobe-files" }, { "Effect": "Allow", "Principal": { "AWS": ["*"] }, "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::lobe-files", "Condition": { "StringEquals": { "s3:prefix": ["files/"] } } }, { "Effect": "Allow", "Principal": { "AWS": ["*"] }, "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"], "Resource": "arn:aws:s3:::lobe-files/files/*" } ] }该策略允许客户端对files/目录下的对象进行读写删操作,同时防止越权访问其他路径。
第七步:启动服务
进入项目目录并启动:
cd ~/lobechat docker-compose up -d首次运行会拉取多个镜像,可能耗时几分钟。可通过日志查看初始化进度:
docker-compose logs -f重点关注postgresql和logto是否健康启动。
第八步:配置 Logto 认证服务
- 浏览器访问:
https://auth-ui.yourdomain.com - 注册管理员账号
- 创建新应用(Application):
- 类型:Machine to Machine 或 SPA
- 名称:LobeChat
- Redirect URI:https://chat.yourdomain.com/api/auth/callback/logto
- Post sign-out redirect URI:https://chat.yourdomain.com
- CORS origins:https://chat.yourdomain.com - 保存后记录生成的 Client ID 和 Secret
- 更新
.env文件中的LOGTO_CLIENT_ID和LOGTO_CLIENT_SECRET - 重启服务使变更生效:
docker-compose down && docker-compose up -d这一步是整个系统的“身份门禁”,务必确保回调地址拼写准确,否则会出现重定向错误。
第九步:配置 MinIO 存储服务
- 访问
https://s3-ui.yourdomain.com,使用默认凭据登录:
- 用户名:admin
- 密码:minioadmin12345 - 创建 Bucket:
- 名称:lobe-files(需与.env中一致)
- 类型:Private - 设置访问策略:
- 进入该 Bucket → Summary → Access Policy
- 选择 “Custom”,粘贴minio-bucket-policy.json内容 - 创建专用访问密钥:
- 进入 Identity → Users → Create User
- 添加新用户(如lobe-user),分配最小必要权限
- 生成新的 Access Key 和 Secret Key - 将新密钥更新至
.env文件中的S3_ACCESS_KEY_ID和S3_SECRET_ACCESS_KEY - 重启服务使配置生效
为什么不直接使用 root 用户?出于安全考虑,生产环境中应遵循最小权限原则,避免主账户密钥泄露造成全局风险。
最终验证:打开属于你的 AI 助手
一切就绪后,访问:
👉 https://chat.yourdomain.com
使用你在 Logto 中注册的账号登录,即可进入 LobeChat 主界面,体验以下功能:
- 多模型切换(OpenAI/Gemini/Ollama)
- 插件系统(联网搜索、代码解释器)
- 角色预设与长期记忆
- 文件上传与内容分析
- 语音输入输出(浏览器支持前提下)
你会发现,它的交互逻辑几乎与主流商业产品无异,但所有的对话历史、上传文件、配置信息都牢牢掌握在你自己手中。
维护与优化建议
数据持久化保障
本方案已通过 Docker Volume 实现关键数据持久化:
- PostgreSQL 数据落盘于./data
- MinIO 文件存储于./s3_data
即使容器重建或服务重启,数据也不会丢失。
版本升级策略
定期更新镜像以获得最新功能和安全补丁:
docker-compose pull docker-compose down docker-compose up -d建议结合 CI/CD 工具自动化此流程,例如 GitHub Actions 或 Jenkins。
故障排查要点
遇到问题时,优先检查以下几项:
- 容器日志:docker-compose logs -f <service>
- 网络连通性:确认防火墙放行 80/443/9000/9001 端口
- 证书有效性:避免因过期导致 HTTPS 失败
-.env文件拼写:URL 缺失斜杠、密钥格式错误是常见低级失误
扩展方向
这套部署并非终点,而是起点。你可以进一步:
-接入本地大模型:部署 Ollama 或 llama.cpp,实现免外网调用
-集成企业身份系统:通过 OIDC 协议对接 Azure AD、Keycloak 等统一认证平台
-高可用演进:生产环境建议迁移到 Kubernetes,配合 TLS Ingress 和外部数据库提升稳定性
这种基于 Docker Compose 的轻量级部署模式,既降低了入门门槛,又保留了足够的扩展空间。无论是个人开发者用来搭建私人知识库,还是小团队构建内部客服机器人,都能快速见效。更重要的是,它让我们重新拿回了对 AI 应用的数据主权——这才是私有化部署最根本的价值所在。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考