575 lines
13 KiB
Markdown
575 lines
13 KiB
Markdown
# Cosmo Docker 部署指南
|
||
|
||
## 📦 系统架构
|
||
|
||
### 服务组件
|
||
|
||
| 服务 | 镜像版本 | 说明 | 配置位置 |
|
||
|------|---------|------|---------|
|
||
| **PostgreSQL** | `postgres:15-alpine` | 数据库 | `docker-compose.yml` |
|
||
| **Redis** | `redis:7-alpine` | 缓存服务 | `docker-compose.yml` |
|
||
| **Backend** | `python:3.12-slim` | FastAPI 后端 | `backend/Dockerfile` |
|
||
| **Frontend Build** | `node:22-alpine` | Vite 构建环境 | `frontend/Dockerfile` |
|
||
| **Frontend Server** | `nginx:1.25-alpine` | 静态文件服务 | `frontend/Dockerfile` |
|
||
|
||
### 版本说明
|
||
|
||
- **PostgreSQL 15**: 稳定的长期支持版本,性能优秀
|
||
- **Redis 7**: 最新稳定版,支持更多数据结构和优化
|
||
- **Python 3.12**: 最新稳定版,性能提升显著
|
||
- **Node 22**: LTS 长期支持版本,与开发环境一致
|
||
- **Nginx 1.25**: 稳定版本,完整支持 HTTP/2 和性能优化
|
||
|
||
## 🚀 镜像加速配置
|
||
|
||
### 已配置的加速
|
||
|
||
本项目已预配置以下镜像加速,无需额外配置:
|
||
|
||
#### 1. Docker 基础镜像
|
||
- 使用华为云 SWR 镜像仓库
|
||
- 地址: `swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/`
|
||
|
||
#### 2. 系统软件包(Debian/Alpine)
|
||
- **Backend (Debian)**: 阿里云 APT 镜像
|
||
- `mirrors.aliyun.com`
|
||
- **Frontend (Alpine)**: 自动使用最近的镜像源
|
||
|
||
#### 3. Python 依赖(pip)
|
||
- 阿里云 PyPI 镜像
|
||
- 地址: `https://mirrors.aliyun.com/pypi/simple/`
|
||
- 配置文件: `backend/pip.conf`
|
||
|
||
#### 4. Node.js 依赖(npm)
|
||
- 阿里云 npm 镜像(npmmirror)
|
||
- 地址: `https://registry.npmmirror.com`
|
||
- 配置文件: `frontend/.npmrc`
|
||
|
||
### 加速效果
|
||
|
||
| 操作 | 未加速 | 已加速 | 提升 |
|
||
|------|--------|--------|------|
|
||
| 拉取基础镜像 | ~2-3 分钟 | ~20-30 秒 | **6x** ⚡ |
|
||
| apt-get update | ~1 分钟 | ~10 秒 | **6x** ⚡ |
|
||
| pip install | ~3-5 分钟 | ~30-60 秒 | **5x** ⚡ |
|
||
| npm install | ~5-10 分钟 | ~1-2 分钟 | **5x** ⚡ |
|
||
| **总构建时间** | **~15-20 分钟** | **~3-5 分钟** | **4-5x** ⚡ |
|
||
|
||
### 开发环境配置
|
||
|
||
开发时如需使用镜像加速:
|
||
|
||
#### Python 开发
|
||
```bash
|
||
# 方式 1: 使用配置文件
|
||
export PIP_CONFIG_FILE=./backend/pip.conf
|
||
pip install -r requirements.txt
|
||
|
||
# 方式 2: 命令行指定
|
||
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
|
||
```
|
||
|
||
#### Node.js 开发
|
||
```bash
|
||
# 方式 1: 项目已有 .npmrc,直接使用
|
||
cd frontend
|
||
npm install
|
||
|
||
# 方式 2: 临时使用
|
||
npm install --registry=https://registry.npmmirror.com
|
||
```
|
||
|
||
### 其他可选镜像源
|
||
|
||
如果阿里云镜像不可用,可以使用以下备选:
|
||
|
||
#### Docker 镜像
|
||
- 腾讯云: `mirror.ccs.tencentyun.com`
|
||
- 网易: `hub-mirror.c.163.com`
|
||
- Docker 中国: `registry.docker-cn.com`
|
||
|
||
#### npm 镜像
|
||
- 淘宝镜像: `https://registry.npmmirror.com`
|
||
- 腾讯云: `https://mirrors.cloud.tencent.com/npm/`
|
||
|
||
#### PyPI 镜像
|
||
- 清华大学: `https://pypi.tuna.tsinghua.edu.cn/simple`
|
||
- 豆瓣: `https://pypi.douban.com/simple`
|
||
- 腾讯云: `https://mirrors.cloud.tencent.com/pypi/simple`
|
||
|
||
## 📋 目录结构
|
||
|
||
```
|
||
cosmo/
|
||
├── docker-compose.yml # Docker Compose 配置
|
||
├── .env.production # 生产环境变量(需配置)
|
||
├── deploy.sh # 一键部署脚本
|
||
├── nginx/
|
||
│ └── nginx.conf # Nginx 反向代理配置
|
||
├── backend/
|
||
│ ├── Dockerfile # 后端镜像配置
|
||
│ ├── .dockerignore
|
||
│ └── scripts/
|
||
│ └── init_db.sql # 数据库初始化 SQL
|
||
└── frontend/
|
||
├── Dockerfile # 前端镜像配置(多阶段构建)
|
||
└── .dockerignore
|
||
```
|
||
|
||
## 🚀 快速开始
|
||
|
||
### 前置要求
|
||
|
||
- Docker 20.10+
|
||
- Docker Compose 2.0+
|
||
- 至少 4GB 可用内存
|
||
- 至少 20GB 可用磁盘空间
|
||
|
||
### 1. 配置环境变量
|
||
|
||
编辑 `.env.production` 文件:
|
||
|
||
```bash
|
||
# 修改数据库密码(必须)
|
||
DATABASE_PASSWORD=your_secure_password_here
|
||
|
||
# 修改 JWT Secret Key(必须,用于生成和验证 JWT token)
|
||
# 使用随机字符串,至少 32 位
|
||
JWT_SECRET_KEY=your-random-secret-key-at-least-32-characters-long
|
||
|
||
# 修改 CORS 配置(支持内网 IP 和外网域名访问)
|
||
# 方式 1: 允许所有来源(开发/测试环境)
|
||
CORS_ORIGINS=*
|
||
|
||
# 方式 2: 仅允许特定 IP(内网访问)
|
||
CORS_ORIGINS=http://192.168.1.100
|
||
|
||
# 方式 3: 仅允许特定域名(外网访问)
|
||
CORS_ORIGINS=http://your-domain.com,https://your-domain.com
|
||
|
||
# 方式 4: 同时允许内网 IP 和外网域名(推荐生产环境)
|
||
CORS_ORIGINS=http://192.168.1.100,http://your-domain.com,https://your-domain.com
|
||
|
||
# 前端 API 地址配置
|
||
# 推荐:留空(默认),让前端使用相对路径 /api,自动适配所有访问方式
|
||
# VITE_API_BASE_URL=
|
||
|
||
# 如果前后端分离部署在不同服务器,才需要设置完整地址:
|
||
# VITE_API_BASE_URL=http://your-domain.com/api
|
||
|
||
# HTTP 代理配置(用于访问 NASA JPL Horizons API)
|
||
# 如果服务器在中国境内无法直接访问 NASA API,需要配置 HTTP 代理
|
||
# 格式:http://host:port 或 https://host:port
|
||
# 示例:HTTP_PROXY=http://192.168.124.203:20171
|
||
HTTP_PROXY=
|
||
HTTPS_PROXY=
|
||
```
|
||
|
||
**重要说明**:
|
||
- `CORS_ORIGINS` 使用逗号分隔多个来源,无需引号或方括号
|
||
- 每个来源必须包含协议(http:// 或 https://)
|
||
- 不要在来源末尾添加斜杠
|
||
- 使用 `*` 允许所有来源(仅用于开发环境)
|
||
- **推荐不设置 `VITE_API_BASE_URL`**,让前端使用相对路径,自动适配内网 IP 和外网域名访问
|
||
|
||
### 2. 初始化部署
|
||
|
||
```bash
|
||
# 赋予执行权限
|
||
chmod +x deploy.sh
|
||
|
||
# 初始化系统(首次部署)
|
||
./deploy.sh --init
|
||
```
|
||
|
||
初始化脚本会自动:
|
||
1. ✅ 创建数据目录 `/opt/cosmo/data`
|
||
2. ✅ 构建 Docker 镜像
|
||
3. ✅ 启动 PostgreSQL 和 Redis
|
||
4. ✅ 自动执行 `init_db.sql` 初始化数据库
|
||
5. ✅ 启动所有服务
|
||
|
||
### 3. 访问系统
|
||
|
||
- **前端**: http://your-server-ip
|
||
- **后端 API**: http://your-server-ip/api
|
||
- **API 文档**: http://your-server-ip/api/docs
|
||
|
||
## 📂 数据持久化
|
||
|
||
所有数据存储在 `/opt/cosmo/data/` 目录下:
|
||
|
||
```
|
||
/opt/cosmo/data/
|
||
├── postgres/ # PostgreSQL 数据文件
|
||
├── redis/ # Redis 持久化文件
|
||
├── upload/ # 用户上传文件(纹理、模型等)
|
||
├── logs/ # 应用日志
|
||
│ └── backend/ # 后端日志
|
||
└── backups/ # 备份文件
|
||
```
|
||
|
||
### 目录权限
|
||
|
||
```bash
|
||
sudo chown -R $(whoami):$(whoami) /opt/cosmo/data
|
||
sudo chmod -R 755 /opt/cosmo/data
|
||
```
|
||
|
||
## 🛠️ 常用命令
|
||
|
||
### 服务管理
|
||
|
||
```bash
|
||
# 启动服务
|
||
./deploy.sh --start
|
||
|
||
# 停止服务
|
||
./deploy.sh --stop
|
||
|
||
# 重启服务
|
||
./deploy.sh --restart
|
||
|
||
# 查看状态
|
||
./deploy.sh --status
|
||
|
||
# 查看日志
|
||
./deploy.sh --logs
|
||
```
|
||
|
||
### 数据备份
|
||
|
||
```bash
|
||
# 创建备份(数据库 + 上传文件)
|
||
./deploy.sh --backup
|
||
|
||
# 备份文件位置
|
||
ls -lh /opt/cosmo/data/backups/
|
||
```
|
||
|
||
### 系统更新
|
||
|
||
```bash
|
||
# 拉取最新代码并重启
|
||
./deploy.sh --update
|
||
```
|
||
|
||
### 清理操作
|
||
|
||
```bash
|
||
# 删除容器(保留数据)
|
||
./deploy.sh --clean
|
||
|
||
# 完全清除(删除容器和所有数据)⚠️ 危险操作
|
||
./deploy.sh --full-clean
|
||
```
|
||
|
||
## 🔧 手动操作
|
||
|
||
### 查看容器状态
|
||
|
||
```bash
|
||
docker-compose ps
|
||
```
|
||
|
||
### 进入容器
|
||
|
||
```bash
|
||
# 进入后端容器
|
||
docker-compose exec backend bash
|
||
|
||
# 进入数据库容器
|
||
docker-compose exec postgres psql -U postgres -d cosmo_db
|
||
```
|
||
|
||
### 查看日志
|
||
|
||
```bash
|
||
# 查看所有日志
|
||
docker-compose logs -f
|
||
|
||
# 查看特定服务日志
|
||
docker-compose logs -f backend
|
||
docker-compose logs -f postgres
|
||
```
|
||
|
||
### 重启单个服务
|
||
|
||
```bash
|
||
docker-compose restart backend
|
||
docker-compose restart frontend
|
||
```
|
||
|
||
## 🔒 生产环境安全配置
|
||
|
||
### 1. 修改默认密码
|
||
|
||
编辑 `.env.production`:
|
||
```bash
|
||
DATABASE_PASSWORD=strong_random_password_here
|
||
```
|
||
|
||
### 2. 配置 HTTPS(推荐)
|
||
|
||
使用 Let's Encrypt 免费证书:
|
||
|
||
```bash
|
||
# 安装 certbot
|
||
sudo apt install certbot python3-certbot-nginx
|
||
|
||
# 获取证书
|
||
sudo certbot --nginx -d your-domain.com
|
||
|
||
# 证书自动续期
|
||
sudo crontab -e
|
||
# 添加: 0 3 * * * certbot renew --quiet
|
||
```
|
||
|
||
修改 `nginx/nginx.conf` 添加 SSL 配置:
|
||
|
||
```nginx
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name your-domain.com;
|
||
|
||
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
||
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
||
|
||
# 其他配置...
|
||
}
|
||
|
||
# HTTP 重定向到 HTTPS
|
||
server {
|
||
listen 80;
|
||
server_name your-domain.com;
|
||
return 301 https://$server_name$request_uri;
|
||
}
|
||
```
|
||
|
||
### 3. 防火墙配置
|
||
|
||
```bash
|
||
# 开放端口
|
||
sudo ufw allow 80/tcp
|
||
sudo ufw allow 443/tcp
|
||
sudo ufw enable
|
||
|
||
# 限制数据库和 Redis 只能内部访问
|
||
# docker-compose.yml 中不要映射 5432 和 6379 到宿主机
|
||
```
|
||
|
||
## 📊 监控和日志
|
||
|
||
### 查看资源使用
|
||
|
||
```bash
|
||
docker stats
|
||
```
|
||
|
||
### 日志轮转
|
||
|
||
创建 `/etc/logrotate.d/cosmo`:
|
||
|
||
```
|
||
/opt/cosmo/data/logs/backend/*.log {
|
||
daily
|
||
rotate 7
|
||
compress
|
||
delaycompress
|
||
notifempty
|
||
create 0640 www-data www-data
|
||
sharedscripts
|
||
}
|
||
```
|
||
|
||
## 🐛 故障排查
|
||
|
||
### 前端 API 请求配置
|
||
|
||
前端的 API 地址有三种工作模式(见 `frontend/src/utils/request.ts`):
|
||
|
||
1. **生产模式(推荐)** - 使用相对路径 `/api`
|
||
- **配置**: 不设置或注释掉 `VITE_API_BASE_URL`
|
||
- **工作原理**: 请求发送到当前访问地址的 `/api` 路径,由 Nginx 反向代理到后端
|
||
- **优点**: 自动适配所有访问方式(内网 IP、外网域名)
|
||
- **示例**:
|
||
- 访问 `http://192.168.1.100` → API 请求到 `http://192.168.1.100/api`
|
||
- 访问 `http://domain.com` → API 请求到 `http://domain.com/api`
|
||
|
||
2. **指定完整 API 地址** - 跨域或前后端分离部署
|
||
- **配置**: `VITE_API_BASE_URL=http://your-server.com/api`
|
||
- **工作原理**: 所有 API 请求都发送到指定的完整地址
|
||
- **缺点**: 只能指定一个地址,无法同时支持多种访问方式
|
||
|
||
3. **开发模式** - 自动检测
|
||
- **配置**: 不设置 `VITE_API_BASE_URL` + `npm run dev`
|
||
- **工作原理**: 自动使用 `http://当前主机名:8000/api`
|
||
|
||
**常见问题**:
|
||
|
||
❌ **问题**: 内网 IP 访问时,API 请求跳到外网域名
|
||
```bash
|
||
# 原因:设置了完整的 API 地址
|
||
VITE_API_BASE_URL=http://your-domain.com/api
|
||
```
|
||
✅ **解决**: 注释掉或删除 `VITE_API_BASE_URL`,让前端使用相对路径
|
||
|
||
❌ **问题**: API 请求 404 Not Found
|
||
```bash
|
||
# 检查 Nginx 是否正常运行
|
||
docker-compose ps frontend
|
||
docker-compose logs frontend
|
||
|
||
# 检查 Nginx 配置是否正确
|
||
docker-compose exec frontend nginx -t
|
||
```
|
||
|
||
### CORS 配置错误
|
||
|
||
**错误信息**:
|
||
```
|
||
pydantic_settings.sources.SettingsError: error parsing value for field "cors_origins"
|
||
```
|
||
|
||
**原因**: CORS_ORIGINS 配置格式错误
|
||
|
||
**解决方案**:
|
||
```bash
|
||
# ✅ 正确格式(逗号分隔,无引号)
|
||
CORS_ORIGINS=http://192.168.1.100,http://domain.com,https://domain.com
|
||
|
||
# ✅ 允许所有来源
|
||
CORS_ORIGINS=*
|
||
|
||
# ❌ 错误格式(不要使用 JSON 数组格式)
|
||
CORS_ORIGINS=["http://domain.com", "https://domain.com"]
|
||
|
||
# ❌ 错误格式(不要在域名后加斜杠)
|
||
CORS_ORIGINS=http://domain.com/,https://domain.com/
|
||
```
|
||
|
||
修改 `.env.production` 后需要重启服务:
|
||
```bash
|
||
./deploy.sh --restart
|
||
```
|
||
|
||
### 服务启动失败
|
||
|
||
1. 查看日志:
|
||
```bash
|
||
docker-compose logs backend
|
||
```
|
||
|
||
2. 检查数据库连接:
|
||
```bash
|
||
docker-compose exec backend python -c "from app.database import engine; print('DB OK')"
|
||
```
|
||
|
||
### 数据库连接失败
|
||
|
||
```bash
|
||
# 检查数据库是否就绪
|
||
docker-compose exec postgres pg_isready -U postgres
|
||
|
||
# 查看数据库日志
|
||
docker-compose logs postgres
|
||
```
|
||
|
||
### 前端访问 502
|
||
|
||
1. 检查后端是否运行:
|
||
```bash
|
||
docker-compose ps backend
|
||
curl http://localhost:8000/health
|
||
```
|
||
|
||
2. 检查 Nginx 配置:
|
||
```bash
|
||
docker-compose exec frontend nginx -t
|
||
```
|
||
|
||
### 磁盘空间不足
|
||
|
||
```bash
|
||
# 清理未使用的镜像和容器
|
||
docker system prune -a
|
||
|
||
# 检查磁盘使用
|
||
df -h /opt/cosmo/data
|
||
```
|
||
|
||
## 📝 版本升级
|
||
|
||
### 升级流程
|
||
|
||
1. 备份数据:
|
||
```bash
|
||
./deploy.sh --backup
|
||
```
|
||
|
||
2. 拉取最新代码:
|
||
```bash
|
||
git pull origin main
|
||
```
|
||
|
||
3. 重建镜像:
|
||
```bash
|
||
docker-compose build --no-cache
|
||
```
|
||
|
||
4. 重启服务:
|
||
```bash
|
||
docker-compose down
|
||
docker-compose up -d
|
||
```
|
||
|
||
## 🔄 数据迁移
|
||
|
||
### 导出数据
|
||
|
||
```bash
|
||
# 导出数据库
|
||
docker-compose exec postgres pg_dump -U postgres cosmo_db > cosmo_backup.sql
|
||
|
||
# 打包上传文件
|
||
tar -czf upload_backup.tar.gz /opt/cosmo/data/upload
|
||
```
|
||
|
||
### 导入数据
|
||
|
||
```bash
|
||
# 导入数据库
|
||
docker-compose exec -T postgres psql -U postgres cosmo_db < cosmo_backup.sql
|
||
|
||
# 恢复上传文件
|
||
tar -xzf upload_backup.tar.gz -C /opt/cosmo/data/
|
||
```
|
||
|
||
## 📞 技术支持
|
||
|
||
- 项目文档: [README.md](./README.md)
|
||
- Issue 反馈: GitHub Issues
|
||
- 配置说明: [CONFIG.md](./backend/CONFIG.md)
|
||
|
||
## 🎯 性能优化建议
|
||
|
||
1. **数据库优化**:
|
||
- 增加 `shared_buffers` 至系统内存的 25%
|
||
- 启用连接池复用
|
||
|
||
2. **Redis 优化**:
|
||
- 根据需要调整 `maxmemory` 配置
|
||
- 使用 AOF 持久化策略
|
||
|
||
3. **Nginx 优化**:
|
||
- 启用 gzip 压缩(已配置)
|
||
- 配置静态资源缓存(已配置)
|
||
|
||
4. **Docker 优化**:
|
||
- 为容器设置资源限制
|
||
- 使用 SSD 存储数据
|
||
|
||
---
|
||
|
||
**祝部署顺利!🚀**
|