Dockerfile

This commit is contained in:
2025-11-10 22:23:42 +08:00
parent f211e2ff48
commit 5a5377e945
10 changed files with 1099 additions and 2 deletions

92
.env.example Normal file
View 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
View 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
View 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
View 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.

View File

@@ -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
View 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
View 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
View 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
View 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;
}
}