Dockerfile
This commit is contained in:
92
.env.example
Normal file
92
.env.example
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# ======================================
|
||||||
|
# AI Router Docker 环境变量配置示例
|
||||||
|
# ======================================
|
||||||
|
#
|
||||||
|
# 使用说明:
|
||||||
|
# 1. 复制此文件为 .env
|
||||||
|
# 2. 根据实际情况修改配置值
|
||||||
|
# 3. 不要将 .env 文件提交到版本控制系统
|
||||||
|
#
|
||||||
|
|
||||||
|
# ======================================
|
||||||
|
# 后端服务配置
|
||||||
|
# ======================================
|
||||||
|
|
||||||
|
# 数据库文件路径
|
||||||
|
# 默认值:/app/data/gateway.db
|
||||||
|
# 说明:在 Docker 容器中,数据库文件会存储在此路径
|
||||||
|
DB_PATH=/app/data/gateway.db
|
||||||
|
|
||||||
|
# 后端服务端口
|
||||||
|
# 默认值:8080
|
||||||
|
# 说明:后端 API 服务监听的端口
|
||||||
|
BACKEND_PORT=8080
|
||||||
|
|
||||||
|
# 后端服务主机地址(仅在需要修改时设置)
|
||||||
|
# 默认值:0.0.0.0
|
||||||
|
# BACKEND_HOST=0.0.0.0
|
||||||
|
|
||||||
|
# ======================================
|
||||||
|
# 前端服务配置
|
||||||
|
# ======================================
|
||||||
|
|
||||||
|
# 前端服务端口
|
||||||
|
# 默认值:3000
|
||||||
|
# 说明:前端 Web 界面访问端口
|
||||||
|
FRONTEND_PORT=3000
|
||||||
|
|
||||||
|
# API 基础路径(前端调用后端 API 的地址)
|
||||||
|
# 默认值:http://localhost:8080
|
||||||
|
# 说明:在生产环境中,应该设置为实际的后端服务地址
|
||||||
|
# VITE_API_BASE_URL=http://localhost:8080
|
||||||
|
|
||||||
|
# ======================================
|
||||||
|
# Docker Compose 配置
|
||||||
|
# ======================================
|
||||||
|
|
||||||
|
# 项目名称
|
||||||
|
# 默认值:ai-router
|
||||||
|
# 说明:Docker Compose 会使用此名称作为容器、网络、卷的前缀
|
||||||
|
COMPOSE_PROJECT_NAME=ai-router
|
||||||
|
|
||||||
|
# ======================================
|
||||||
|
# 日志配置
|
||||||
|
# ======================================
|
||||||
|
|
||||||
|
# 日志级别
|
||||||
|
# 可选值:debug, info, warn, error
|
||||||
|
# 默认值:info
|
||||||
|
LOG_LEVEL=info
|
||||||
|
|
||||||
|
# ======================================
|
||||||
|
# 数据库配置(高级选项)
|
||||||
|
# ======================================
|
||||||
|
|
||||||
|
# 数据库备份目录
|
||||||
|
# 说明:可以挂载一个额外的卷用于数据库备份
|
||||||
|
# BACKUP_PATH=/app/backups
|
||||||
|
|
||||||
|
# ======================================
|
||||||
|
# 网络配置(高级选项)
|
||||||
|
# ======================================
|
||||||
|
|
||||||
|
# 是否启用 HTTPS
|
||||||
|
# 默认值:false
|
||||||
|
# 说明:如果启用,需要配置 SSL 证书
|
||||||
|
# ENABLE_HTTPS=false
|
||||||
|
|
||||||
|
# SSL 证书路径(启用 HTTPS 时需要)
|
||||||
|
# SSL_CERT_PATH=/etc/ssl/certs/cert.pem
|
||||||
|
# SSL_KEY_PATH=/etc/ssl/private/key.pem
|
||||||
|
|
||||||
|
# ======================================
|
||||||
|
# 性能优化配置
|
||||||
|
# ======================================
|
||||||
|
|
||||||
|
# Go 运行时最大处理器数
|
||||||
|
# 默认值:自动检测
|
||||||
|
# GOMAXPROCS=4
|
||||||
|
|
||||||
|
# Node.js 内存限制(MB)
|
||||||
|
# 默认值:4096
|
||||||
|
# NODE_OPTIONS=--max-old-space-size=4096
|
||||||
699
README-DOCKER.md
Normal file
699
README-DOCKER.md
Normal file
@@ -0,0 +1,699 @@
|
|||||||
|
# AI Router Docker 部署指南
|
||||||
|
|
||||||
|
本文档提供了 AI Router 项目的 Docker 容器化部署完整指南。
|
||||||
|
|
||||||
|
## 📋 目录
|
||||||
|
|
||||||
|
- [系统架构](#系统架构)
|
||||||
|
- [前置要求](#前置要求)
|
||||||
|
- [快速开始](#快速开始)
|
||||||
|
- [详细配置](#详细配置)
|
||||||
|
- [构建和运行](#构建和运行)
|
||||||
|
- [管理和维护](#管理和维护)
|
||||||
|
- [故障排查](#故障排查)
|
||||||
|
- [性能优化](#性能优化)
|
||||||
|
- [安全建议](#安全建议)
|
||||||
|
|
||||||
|
## 🏗️ 系统架构
|
||||||
|
|
||||||
|
本项目使用 Docker Compose 编排两个主要服务:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ Docker Host │
|
||||||
|
│ │
|
||||||
|
│ ┌────────────────────────────────────┐ │
|
||||||
|
│ │ Frontend Container (Nginx) │ │
|
||||||
|
│ │ 端口: 3000 → 80 │ │
|
||||||
|
│ │ - React 应用 │ │
|
||||||
|
│ │ - Nginx 静态文件服务 │ │
|
||||||
|
│ │ - API 请求代理 │ │
|
||||||
|
│ └────────────────┬───────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ │ API 代理 │
|
||||||
|
│ ↓ │
|
||||||
|
│ ┌────────────────────────────────────┐ │
|
||||||
|
│ │ Backend Container (Go) │ │
|
||||||
|
│ │ 端口: 8080 │ │
|
||||||
|
│ │ - Go API 服务 │ │
|
||||||
|
│ │ - SQLite 数据库 │ │
|
||||||
|
│ └────────────────┬───────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ↓ │
|
||||||
|
│ ┌────────────────────────────────────┐ │
|
||||||
|
│ │ Volume: backend-data │ │
|
||||||
|
│ │ 持久化数据库文件 │ │
|
||||||
|
│ └────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 容器说明
|
||||||
|
|
||||||
|
#### 前端容器 (ai-router-frontend)
|
||||||
|
- **基础镜像**: nginx:1.27-alpine
|
||||||
|
- **构建方式**: 多阶段构建(Node.js 构建 + Nginx 运行)
|
||||||
|
- **端口映射**: 3000:80
|
||||||
|
- **功能**:
|
||||||
|
- 托管 React 静态文件
|
||||||
|
- 支持 React Router 的 HTML5 History API
|
||||||
|
- 将 `/api/*` 请求代理到后端服务
|
||||||
|
- 提供健康检查端点 `/health`
|
||||||
|
|
||||||
|
#### 后端容器 (ai-router-backend)
|
||||||
|
- **基础镜像**: debian:bookworm-slim
|
||||||
|
- **构建方式**: 多阶段构建(Go 编译 + 精简运行环境)
|
||||||
|
- **端口映射**: 8080:8080
|
||||||
|
- **功能**:
|
||||||
|
- 提供 RESTful API 服务
|
||||||
|
- 管理 SQLite 数据库
|
||||||
|
- 处理 AI 模型路由逻辑
|
||||||
|
- 提供健康检查端点
|
||||||
|
|
||||||
|
## 📦 前置要求
|
||||||
|
|
||||||
|
### 必需软件
|
||||||
|
|
||||||
|
- **Docker**: 版本 20.10.0 或更高
|
||||||
|
- **Docker Compose**: 版本 2.0.0 或更高
|
||||||
|
|
||||||
|
### 检查安装
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查 Docker 版本
|
||||||
|
docker --version
|
||||||
|
|
||||||
|
# 检查 Docker Compose 版本
|
||||||
|
docker compose version
|
||||||
|
|
||||||
|
# 验证 Docker 运行状态
|
||||||
|
docker info
|
||||||
|
```
|
||||||
|
|
||||||
|
### 系统要求
|
||||||
|
|
||||||
|
- **最低配置**:
|
||||||
|
- CPU: 2 核
|
||||||
|
- 内存: 2GB
|
||||||
|
- 磁盘空间: 5GB
|
||||||
|
|
||||||
|
- **推荐配置**:
|
||||||
|
- CPU: 4 核或更多
|
||||||
|
- 内存: 4GB 或更多
|
||||||
|
- 磁盘空间: 10GB 或更多
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 1. 克隆项目(如果还没有)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd ai_router
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 配置环境变量(可选)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 复制环境变量示例文件
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
# 根据需要编辑 .env 文件
|
||||||
|
# 默认配置已经可以直接使用
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 构建并启动服务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 构建镜像并启动所有服务
|
||||||
|
docker compose up --build -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 验证部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看容器运行状态
|
||||||
|
docker compose ps
|
||||||
|
|
||||||
|
# 查看服务日志
|
||||||
|
docker compose logs -f
|
||||||
|
|
||||||
|
# 检查前端服务
|
||||||
|
curl http://localhost:3000/health
|
||||||
|
|
||||||
|
# 检查后端服务
|
||||||
|
curl http://localhost:8080/api/providers
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. 访问应用
|
||||||
|
|
||||||
|
- **前端界面**: http://localhost:3000
|
||||||
|
- **后端 API**: http://localhost:8080/api
|
||||||
|
|
||||||
|
## ⚙️ 详细配置
|
||||||
|
|
||||||
|
### 环境变量配置
|
||||||
|
|
||||||
|
项目支持通过环境变量进行配置。创建 `.env` 文件或在 `docker-compose.yml` 中直接设置。
|
||||||
|
|
||||||
|
#### 核心配置
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 数据库路径
|
||||||
|
DB_PATH=/app/data/gateway.db
|
||||||
|
|
||||||
|
# 服务端口
|
||||||
|
BACKEND_PORT=8080
|
||||||
|
FRONTEND_PORT=3000
|
||||||
|
|
||||||
|
# 日志级别
|
||||||
|
LOG_LEVEL=info
|
||||||
|
|
||||||
|
# 项目名称
|
||||||
|
COMPOSE_PROJECT_NAME=ai-router
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 修改端口映射
|
||||||
|
|
||||||
|
如果需要修改对外暴露的端口,编辑 `docker-compose.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
ports:
|
||||||
|
- "自定义端口:8080" # 例如 "9000:8080"
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
ports:
|
||||||
|
- "自定义端口:80" # 例如 "8080:80"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 数据持久化
|
||||||
|
|
||||||
|
后端数据库文件通过 Docker Volume 持久化:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看数据卷
|
||||||
|
docker volume ls | grep ai-router
|
||||||
|
|
||||||
|
# 查看数据卷详情
|
||||||
|
docker volume inspect ai-router-backend-data
|
||||||
|
|
||||||
|
# 备份数据卷
|
||||||
|
docker run --rm -v ai-router-backend-data:/data -v $(pwd):/backup alpine tar czf /backup/backup-$(date +%Y%m%d-%H%M%S).tar.gz -C /data .
|
||||||
|
|
||||||
|
# 恢复数据卷
|
||||||
|
docker run --rm -v ai-router-backend-data:/data -v $(pwd):/backup alpine tar xzf /backup/backup-YYYYMMDD-HHMMSS.tar.gz -C /data
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 构建和运行
|
||||||
|
|
||||||
|
### 开发环境
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 启动服务(前台运行,可以看到实时日志)
|
||||||
|
docker compose up
|
||||||
|
|
||||||
|
# 启动服务(后台运行)
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 仅启动特定服务
|
||||||
|
docker compose up backend
|
||||||
|
docker compose up frontend
|
||||||
|
|
||||||
|
# 重新构建并启动
|
||||||
|
docker compose up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 生产环境
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 构建生产镜像
|
||||||
|
docker compose build --no-cache
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 查看服务状态
|
||||||
|
docker compose ps
|
||||||
|
|
||||||
|
# 查看资源使用情况
|
||||||
|
docker stats
|
||||||
|
```
|
||||||
|
|
||||||
|
### 单独构建镜像
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 构建后端镜像
|
||||||
|
cd backend
|
||||||
|
docker build -t ai-router-backend:latest .
|
||||||
|
|
||||||
|
# 构建前端镜像
|
||||||
|
cd frontend
|
||||||
|
docker build -t ai-router-frontend:latest .
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ 管理和维护
|
||||||
|
|
||||||
|
### 查看日志
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看所有服务日志
|
||||||
|
docker compose logs
|
||||||
|
|
||||||
|
# 实时跟踪日志
|
||||||
|
docker compose logs -f
|
||||||
|
|
||||||
|
# 查看特定服务的日志
|
||||||
|
docker compose logs backend
|
||||||
|
docker compose logs frontend
|
||||||
|
|
||||||
|
# 查看最近 100 行日志
|
||||||
|
docker compose logs --tail=100
|
||||||
|
|
||||||
|
# 查看带时间戳的日志
|
||||||
|
docker compose logs -t
|
||||||
|
```
|
||||||
|
|
||||||
|
### 重启服务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 重启所有服务
|
||||||
|
docker compose restart
|
||||||
|
|
||||||
|
# 重启特定服务
|
||||||
|
docker compose restart backend
|
||||||
|
docker compose restart frontend
|
||||||
|
|
||||||
|
# 优雅停止后重启
|
||||||
|
docker compose down && docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 更新服务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 拉取最新代码
|
||||||
|
git pull
|
||||||
|
|
||||||
|
# 重新构建并启动
|
||||||
|
docker compose up --build -d
|
||||||
|
|
||||||
|
# 查看更新后的状态
|
||||||
|
docker compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### 停止和删除
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 停止所有服务
|
||||||
|
docker compose stop
|
||||||
|
|
||||||
|
# 停止并删除容器(保留数据卷)
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# 停止并删除容器和数据卷(谨慎使用!)
|
||||||
|
docker compose down -v
|
||||||
|
|
||||||
|
# 停止并删除所有内容(包括镜像)
|
||||||
|
docker compose down -v --rmi all
|
||||||
|
```
|
||||||
|
|
||||||
|
### 清理系统
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 删除未使用的容器
|
||||||
|
docker container prune
|
||||||
|
|
||||||
|
# 删除未使用的镜像
|
||||||
|
docker image prune
|
||||||
|
|
||||||
|
# 删除未使用的数据卷
|
||||||
|
docker volume prune
|
||||||
|
|
||||||
|
# 清理所有未使用的资源
|
||||||
|
docker system prune -a
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 故障排查
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
|
||||||
|
#### 1. 容器无法启动
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查容器状态
|
||||||
|
docker compose ps
|
||||||
|
|
||||||
|
# 查看详细错误信息
|
||||||
|
docker compose logs
|
||||||
|
|
||||||
|
# 检查端口占用
|
||||||
|
netstat -an | grep 3000
|
||||||
|
netstat -an | grep 8080
|
||||||
|
|
||||||
|
# Windows 系统
|
||||||
|
netstat -ano | findstr "3000"
|
||||||
|
netstat -ano | findstr "8080"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 前端无法连接后端
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查网络连接
|
||||||
|
docker compose exec frontend ping backend
|
||||||
|
|
||||||
|
# 检查后端服务是否正常
|
||||||
|
docker compose exec backend wget -O- http://localhost:8080/api/providers
|
||||||
|
|
||||||
|
# 查看 Nginx 配置
|
||||||
|
docker compose exec frontend cat /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# 查看 Nginx 错误日志
|
||||||
|
docker compose logs frontend | grep error
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. 数据库问题
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 进入后端容器
|
||||||
|
docker compose exec backend sh
|
||||||
|
|
||||||
|
# 检查数据库文件
|
||||||
|
ls -lh /app/data/
|
||||||
|
|
||||||
|
# 查看数据库文件权限
|
||||||
|
ls -l /app/data/gateway.db
|
||||||
|
|
||||||
|
# 检查数据库连接
|
||||||
|
# 在容器内执行应用的健康检查
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. 构建失败
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 清理 Docker 缓存
|
||||||
|
docker builder prune
|
||||||
|
|
||||||
|
# 完全重新构建(不使用缓存)
|
||||||
|
docker compose build --no-cache
|
||||||
|
|
||||||
|
# 检查 Dockerfile 语法
|
||||||
|
docker compose config
|
||||||
|
|
||||||
|
# 查看构建日志
|
||||||
|
docker compose build --progress=plain
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5. 性能问题
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看容器资源使用
|
||||||
|
docker stats
|
||||||
|
|
||||||
|
# 查看容器详细信息
|
||||||
|
docker compose exec backend top
|
||||||
|
docker compose exec frontend top
|
||||||
|
|
||||||
|
# 检查磁盘空间
|
||||||
|
docker system df
|
||||||
|
|
||||||
|
# 查看网络延迟
|
||||||
|
docker compose exec frontend ping -c 5 backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### 健康检查
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 前端健康检查
|
||||||
|
curl -f http://localhost:3000/health || echo "Frontend unhealthy"
|
||||||
|
|
||||||
|
# 后端健康检查
|
||||||
|
curl -f http://localhost:8080/api/providers || echo "Backend unhealthy"
|
||||||
|
|
||||||
|
# 查看容器健康状态
|
||||||
|
docker compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### 调试模式
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 进入容器进行调试
|
||||||
|
docker compose exec backend sh
|
||||||
|
docker compose exec frontend sh
|
||||||
|
|
||||||
|
# 以 root 用户进入
|
||||||
|
docker compose exec -u root backend sh
|
||||||
|
|
||||||
|
# 运行临时调试容器
|
||||||
|
docker run -it --rm --network ai-router-network alpine sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚡ 性能优化
|
||||||
|
|
||||||
|
### 镜像优化
|
||||||
|
|
||||||
|
1. **使用多阶段构建**:已在 Dockerfile 中实现
|
||||||
|
2. **最小化镜像层**:合并 RUN 命令
|
||||||
|
3. **使用 .dockerignore**:已配置,排除不必要的文件
|
||||||
|
|
||||||
|
### 资源限制
|
||||||
|
|
||||||
|
编辑 `docker-compose.yml` 添加资源限制:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '2'
|
||||||
|
memory: 1G
|
||||||
|
reservations:
|
||||||
|
cpus: '1'
|
||||||
|
memory: 512M
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1'
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.5'
|
||||||
|
memory: 256M
|
||||||
|
```
|
||||||
|
|
||||||
|
### 网络优化
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
networks:
|
||||||
|
ai-router-network:
|
||||||
|
driver: bridge
|
||||||
|
driver_opts:
|
||||||
|
com.docker.network.driver.mtu: 1500
|
||||||
|
```
|
||||||
|
|
||||||
|
### 日志优化
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔒 安全建议
|
||||||
|
|
||||||
|
### 1. 使用非 root 用户
|
||||||
|
|
||||||
|
修改 Dockerfile 添加专用用户:
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
# 后端 Dockerfile
|
||||||
|
RUN groupadd -r appuser && useradd -r -g appuser appuser
|
||||||
|
USER appuser
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 网络隔离
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# 限制容器间通信
|
||||||
|
networks:
|
||||||
|
ai-router-network:
|
||||||
|
internal: true # 仅内部通信
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 环境变量安全
|
||||||
|
|
||||||
|
- 不要在 `docker-compose.yml` 中硬编码敏感信息
|
||||||
|
- 使用 `.env` 文件,并将其添加到 `.gitignore`
|
||||||
|
- 生产环境使用 Docker Secrets
|
||||||
|
|
||||||
|
### 4. 定期更新
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 更新基础镜像
|
||||||
|
docker compose pull
|
||||||
|
|
||||||
|
# 重新构建
|
||||||
|
docker compose build --pull
|
||||||
|
|
||||||
|
# 重启服务
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. 限制容器权限
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- NET_BIND_SERVICE
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 监控建议
|
||||||
|
|
||||||
|
### 使用 Docker Stats
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 实时监控
|
||||||
|
docker stats
|
||||||
|
|
||||||
|
# 监控特定容器
|
||||||
|
docker stats ai-router-backend ai-router-frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
### 集成监控工具
|
||||||
|
|
||||||
|
推荐使用以下监控工具:
|
||||||
|
|
||||||
|
- **Prometheus + Grafana**: 指标收集和可视化
|
||||||
|
- **ELK Stack**: 日志聚合和分析
|
||||||
|
- **cAdvisor**: 容器性能监控
|
||||||
|
|
||||||
|
### 日志管理
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 设置日志轮转
|
||||||
|
# 在 docker-compose.yml 中配置
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "5"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🌐 生产部署建议
|
||||||
|
|
||||||
|
### 1. 使用反向代理
|
||||||
|
|
||||||
|
在生产环境中,建议在 Docker 服务前部署 Nginx 或 Traefik 作为反向代理:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
# 示例 Nginx 配置
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name your-domain.com;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:3000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 启用 HTTPS
|
||||||
|
|
||||||
|
使用 Let's Encrypt 免费证书:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 使用 Certbot
|
||||||
|
certbot --nginx -d your-domain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 配置自动重启
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
restart: unless-stopped
|
||||||
|
frontend:
|
||||||
|
restart: unless-stopped
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 数据备份策略
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建自动备份脚本
|
||||||
|
#!/bin/bash
|
||||||
|
BACKUP_DIR="/backup"
|
||||||
|
DATE=$(date +%Y%m%d-%H%M%S)
|
||||||
|
docker run --rm -v ai-router-backend-data:/data -v $BACKUP_DIR:/backup alpine tar czf /backup/db-$DATE.tar.gz -C /data .
|
||||||
|
|
||||||
|
# 添加到 crontab
|
||||||
|
0 2 * * * /path/to/backup-script.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. CI/CD 集成
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# GitHub Actions 示例
|
||||||
|
name: Build and Deploy
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Build images
|
||||||
|
run: docker compose build
|
||||||
|
- name: Push images
|
||||||
|
run: docker compose push
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 维护清单
|
||||||
|
|
||||||
|
### 每日检查
|
||||||
|
- [ ] 查看容器运行状态
|
||||||
|
- [ ] 检查日志是否有错误
|
||||||
|
- [ ] 监控资源使用情况
|
||||||
|
|
||||||
|
### 每周检查
|
||||||
|
- [ ] 备份数据库
|
||||||
|
- [ ] 清理未使用的镜像和容器
|
||||||
|
- [ ] 检查磁盘空间
|
||||||
|
|
||||||
|
### 每月检查
|
||||||
|
- [ ] 更新基础镜像
|
||||||
|
- [ ] 审查安全更新
|
||||||
|
- [ ] 性能优化评估
|
||||||
|
|
||||||
|
## 🆘 获取帮助
|
||||||
|
|
||||||
|
如果遇到问题,可以:
|
||||||
|
|
||||||
|
1. 查看日志:`docker compose logs`
|
||||||
|
2. 检查本文档的故障排查部分
|
||||||
|
3. 查看 GitHub Issues
|
||||||
|
4. 联系项目维护者
|
||||||
|
|
||||||
|
## 📚 相关资源
|
||||||
|
|
||||||
|
- [Docker 官方文档](https://docs.docker.com/)
|
||||||
|
- [Docker Compose 文档](https://docs.docker.com/compose/)
|
||||||
|
- [项目 GitHub](https://github.com/your-repo)
|
||||||
|
- [API 文档](./backend/docs/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**最后更新**: 2025-11-10
|
||||||
|
|
||||||
|
**版本**: 1.0.0
|
||||||
41
backend/.dockerignore
Normal file
41
backend/.dockerignore
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# Git 相关
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# 文档
|
||||||
|
*.md
|
||||||
|
docs/
|
||||||
|
|
||||||
|
# IDE 配置
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# 测试文件
|
||||||
|
*_test.go
|
||||||
|
testdata/
|
||||||
|
|
||||||
|
# 临时文件和日志
|
||||||
|
*.log
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
|
||||||
|
# 操作系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# 数据库文件(构建时不需要)
|
||||||
|
*.db
|
||||||
|
*.db-shm
|
||||||
|
*.db-wal
|
||||||
|
|
||||||
|
# 构建产物
|
||||||
|
main
|
||||||
|
*.exe
|
||||||
|
|
||||||
|
# 环境变量文件
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
42
backend/Dockerfile
Normal file
42
backend/Dockerfile
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# 第一阶段:构建 Go 应用
|
||||||
|
FROM golang:1.24-bookworm AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 复制 go.mod 和 go.sum 文件
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
|
||||||
|
# 下载依赖
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
# 复制所有源代码
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 编译应用程序
|
||||||
|
# CGO_ENABLED=1 是因为 SQLite 驱动需要 CGO
|
||||||
|
RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -o main .
|
||||||
|
|
||||||
|
# 第二阶段:创建最小化的运行镜像
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 安装运行时依赖(SQLite 需要)
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# 从构建阶段复制编译好的二进制文件
|
||||||
|
COPY --from=builder /app/main .
|
||||||
|
|
||||||
|
# 创建数据目录
|
||||||
|
RUN mkdir -p /app/data
|
||||||
|
|
||||||
|
# 暴露后端服务端口
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# 设置默认的数据库路径环境变量
|
||||||
|
ENV DB_PATH=/app/data/gateway.db
|
||||||
|
|
||||||
|
# 启动应用
|
||||||
|
CMD ["./main"]
|
||||||
Binary file not shown.
@@ -2,6 +2,7 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"ai-gateway/internal/models"
|
"ai-gateway/internal/models"
|
||||||
|
"os"
|
||||||
|
|
||||||
"gorm.io/driver/sqlite"
|
"gorm.io/driver/sqlite"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -9,8 +10,14 @@ import (
|
|||||||
|
|
||||||
// InitDB 初始化数据库连接并执行自动迁移
|
// InitDB 初始化数据库连接并执行自动迁移
|
||||||
func InitDB() (*gorm.DB, error) {
|
func InitDB() (*gorm.DB, error) {
|
||||||
// 使用SQLite驱动连接到gateway.db数据库文件
|
// 从环境变量读取数据库路径,如果未设置则使用默认路径
|
||||||
db, err := gorm.Open(sqlite.Open("gateway.db"), &gorm.Config{})
|
dbPath := os.Getenv("DB_PATH")
|
||||||
|
if dbPath == "" {
|
||||||
|
dbPath = "gateway.db"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用SQLite驱动连接到数据库文件
|
||||||
|
db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
59
docker-compose.yml
Normal file
59
docker-compose.yml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
# 后端服务
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: ./backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: ai-router-backend
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
environment:
|
||||||
|
# 数据库文件路径(映射到数据卷)
|
||||||
|
- DB_PATH=/app/data/gateway.db
|
||||||
|
volumes:
|
||||||
|
# 持久化数据库文件
|
||||||
|
- backend-data:/app/data
|
||||||
|
networks:
|
||||||
|
- ai-router-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/api/providers"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
# 前端服务
|
||||||
|
frontend:
|
||||||
|
build:
|
||||||
|
context: ./frontend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: ai-router-frontend
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3000:80"
|
||||||
|
depends_on:
|
||||||
|
backend:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- ai-router-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 20s
|
||||||
|
|
||||||
|
# 数据卷定义
|
||||||
|
volumes:
|
||||||
|
backend-data:
|
||||||
|
driver: local
|
||||||
|
name: ai-router-backend-data
|
||||||
|
|
||||||
|
# 网络定义
|
||||||
|
networks:
|
||||||
|
ai-router-network:
|
||||||
|
driver: bridge
|
||||||
|
name: ai-router-network
|
||||||
59
frontend/.dockerignore
Normal file
59
frontend/.dockerignore
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# 依赖目录
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# 构建产物
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
.vite/
|
||||||
|
|
||||||
|
# Git 相关
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# 文档
|
||||||
|
*.md
|
||||||
|
README.md
|
||||||
|
docs/
|
||||||
|
|
||||||
|
# IDE 和编辑器
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
*.sublime-*
|
||||||
|
|
||||||
|
# 测试相关
|
||||||
|
coverage/
|
||||||
|
.nyc_output/
|
||||||
|
*.spec.js
|
||||||
|
*.spec.jsx
|
||||||
|
*.test.js
|
||||||
|
*.test.jsx
|
||||||
|
|
||||||
|
# 环境变量文件
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
# 操作系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# 临时文件
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
*.tmp
|
||||||
|
|
||||||
|
# ESLint 缓存
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Vite 缓存
|
||||||
|
.vite-inspect/
|
||||||
36
frontend/Dockerfile
Normal file
36
frontend/Dockerfile
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# 第一阶段:构建 React 应用
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 复制 package.json 和 package-lock.json
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
RUN npm ci --only=production=false
|
||||||
|
|
||||||
|
# 复制所有源代码
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 构建生产版本
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# 第二阶段:使用 Nginx 托管静态文件
|
||||||
|
FROM nginx:1.27-alpine
|
||||||
|
|
||||||
|
WORKDIR /usr/share/nginx/html
|
||||||
|
|
||||||
|
# 删除 Nginx 默认的静态文件
|
||||||
|
RUN rm -rf ./*
|
||||||
|
|
||||||
|
# 从构建阶段复制构建好的静态文件
|
||||||
|
COPY --from=builder /app/dist .
|
||||||
|
|
||||||
|
# 复制自定义的 Nginx 配置
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# 暴露前端服务端口
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# 启动 Nginx
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
62
frontend/nginx.conf
Normal file
62
frontend/nginx.conf
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# 启用 gzip 压缩
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_min_length 1024;
|
||||||
|
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
|
||||||
|
|
||||||
|
# 静态资源缓存配置
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# API 代理到后端服务
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://backend:8080;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
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_cache_bypass $http_upgrade;
|
||||||
|
|
||||||
|
# 超时设置
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 支持 React Router 的 HTML5 History API
|
||||||
|
# 所有非文件请求都返回 index.html
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 健康检查端点
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 安全头部
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
|
||||||
|
# 错误页面
|
||||||
|
error_page 404 /index.html;
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user