# Gemini Storyboard 部署指南
本文档详细说明如何将 Gemini Storyboard 项目部署到 Ubuntu 服务器,使用新域名 `aaa.why.vin` 和端口 `8001`。
---
## 一、部署前准备
### 1.1 服务器信息
| 项目 | 值 |
|------|-----|
| 服务器 IP | 175.178.59.129 |
| 操作系统 | Ubuntu |
| 域名 | aaa.why.vin |
| 应用端口 | 8001 |
| 访问地址 | https://aaa.why.vin |
### 1.2 所需文件清单
在本地项目目录 `e:\mianshi\0128\` 中需要准备以下文件:
| 文件名 | 说明 | 是否需要修改 |
|--------|------|-------------|
| `server.py` | FastAPI 应用主文件 | ❌ 否 |
| `Index.html` | 前端页面 | ❌ 否 |
| `Dockerfile` | Docker 镜像构建文件 | ❌ 否 |
| `docker-compose.yml` | Docker 编排配置 | ✅ 是(端口) |
| `requirements.txt` | Python 依赖 | ❌ 否 |
| `.env` | 环境变量配置 | ❌ 否 |
| SSL 证书文件 | 见下方说明 | ✅ 是 |
### 1.3 SSL 证书准备
你需要准备 `aaa.why.vin` 的 SSL 证书文件:
| 文件名 | 说明 |
|--------|------|
| `fullchain.pem` | 完整证书链 |
| `privkey.pem` | 私钥文件 |
**证书获取方式:**
- 通过 1Panel 面板申请 Let's Encrypt 证书
- 或从其他 SSL 证书提供商获取
**证书上传位置:**
- **有 1Panel:** 上传到服务器 `/www/ssl/aaa_why_vin/` 目录
- **无 1Panel:** 上传到服务器 `/etc/ssl/certs/aaa_why_vin/` 目录
---
## 方案选择
根据服务器环境选择部署方案:
| 方案 | 适用场景 | Nginx 类型 |
|------|---------|-----------|
| **方案 A** | 服务器已安装 1Panel | 1Panel OpenResty(Docker 容器) |
| **方案 B** | 服务器无 1Panel | 原生 Nginx |
**如何判断:**
```bash
# 检查是否有 1Panel
docker ps | grep 1Panel
# 如果有输出 → 使用方案 A
# 如果无输出 → 使用方案 B
```
---
## 二、本地文件修改
## 二、本地文件修改
### 2.1 修改 docker-compose.yml(端口改为 8001)
打开 `docker-compose.yml`,修改端口映射:
```yaml
version: '3.8'
services:
app:
build: .
container_name: gemini-storyboard-aaa # 修改容器名,避免冲突
restart: unless-stopped
ports:
- "8001:8000" # 修改为 8001 端口
env_file:
- .env
volumes:
- ./state:/app/state
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
**关键修改点:**
- `container_name`: 改为 `gemini-storyboard-aaa`(避免与 test.why.vin 的容器冲突)
- `ports`: 改为 `"8001:8000"`
---
## 三、服务器端操作 - 方案 A(有 1Panel)
> **使用此方案:** 当服务器已安装 1Panel 时
### 3.1 连接服务器
```bash
ssh ubuntu@175.178.59.129
```
### 3.2 创建项目目录
```bash
# 创建项目目录(与 test.why.vin 分开)
mkdir -p /home/ubuntu/gemini-storyboard-aaa
cd /home/ubuntu/gemini-storyboard-aaa
```
### 3.3 上传项目文件
**使用 Termius SFTP:**
1. 打开 Termius,连接到服务器
2. 点击 SFTP 图标(或按 `Ctrl+P`)
3. 进入 `/home/ubuntu/gemini-storyboard-aaa/` 目录
4. 拖拽以下文件到 SFTP 窗口:
- `server.py`
- `Index.html`
- `Dockerfile`
- `docker-compose.yml`(修改后的)
- `requirements.txt`
- `.env`
### 3.4 上传 SSL 证书
**创建证书目录:**
```bash
# 在服务器上执行
sudo mkdir -p /www/ssl/aaa_why_vin
```
**上传证书文件:**
使用 Termius SFTP 将以下文件上传到 `/www/ssl/aaa_why_vin/`:
- `fullchain.pem`
- `privkey.pem`
**验证证书上传:**
```bash
ls -la /www/ssl/aaa_why_vin/
# 应该看到 fullchain.pem 和 privkey.pem 两个文件
# 验证证书内容
openssl x509 -in /www/ssl/aaa_why_vin/fullchain.pem -noout -subject -dates
# 应该显示 subject=CN = aaa.why.vin
```
### 3.5 开放防火墙端口
```bash
# 开放 8001 端口
sudo ufw allow 8001/tcp
# 确认规则已添加
sudo ufw status | grep 8001
```
### 3.6 构建 Nginx 配置
在服务器上创建 Nginx 配置文件:
```bash
# 创建配置文件
cat > /tmp/aaa_why_vin.conf << 'EOF'
server {
listen 80;
server_name aaa.why.vin;
location / {
proxy_pass http://127.0.0.1:8001;
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";
}
}
server {
listen 443 ssl;
server_name aaa.why.vin;
ssl_certificate /www/sites/aaa.why.vin/ssl/fullchain.pem;
ssl_certificate_key /www/sites/aaa.why.vin/ssl/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8001;
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";
}
}
EOF
```
### 3.7 配置 1Panel Nginx
```bash
# 1. 在容器内创建网站目录和 SSL 目录
docker exec 1Panel-openresty-D5XG mkdir -p /www/sites/aaa.why.vin/ssl
# 2. 复制 SSL 证书到容器
docker cp /www/ssl/aaa_why_vin/fullchain.pem 1Panel-openresty-D5XG:/www/sites/aaa.why.vin/ssl/
docker cp /www/ssl/aaa_why_vin/privkey.pem 1Panel-openresty-D5XG:/www/sites/aaa.why.vin/ssl/
# 3. 验证证书已复制
docker exec 1Panel-openresty-D5XG ls -la /www/sites/aaa.why.vin/ssl/
# 4. 复制 Nginx 配置文件
docker cp /tmp/aaa_why_vin.conf 1Panel-openresty-D5XG:/usr/local/openresty/nginx/conf/conf.d/aaa.why.vin.conf
# 5. 测试 Nginx 配置
docker exec 1Panel-openresty-D5XG nginx -t
# 6. 重新加载 Nginx
docker exec 1Panel-openresty-D5XG nginx -s reload
```
### 3.8 启动 Docker 容器
```bash
# 进入项目目录
cd /home/ubuntu/gemini-storyboard-aaa
# 创建状态目录
mkdir -p state
# 将用户添加到 docker 组(如果还没做)
sudo usermod -aG docker ubuntu
newgrp docker
# 构建并启动容器
docker compose up -d
# 查看容器日志
docker compose logs -f
# 检查容器状态
docker ps | grep gemini-storyboard-aaa
```
---
## 四、服务器端操作 - 方案 B(无 1Panel,使用原生 Nginx)
> **使用此方案:** 当服务器没有 1Panel 时,使用原生 Nginx
### 4.1 安装 Nginx
```bash
# 更新软件包索引
sudo apt-get update
# 安装 Nginx
sudo apt-get install -y nginx
# 验证安装
nginx -v
# 输出示例: nginx version: nginx/1.18.0
```
### 4.2 创建项目目录
```bash
# 创建项目目录
mkdir -p /home/ubuntu/gemini-storyboard-aaa
cd /home/ubuntu/gemini-storyboard-aaa
```
### 4.3 上传项目文件
**使用 Termius SFTP:**
1. 打开 Termius,连接到服务器
2. 点击 SFTP 图标(或按 `Ctrl+P`)
3. 进入 `/home/ubuntu/gemini-storyboard-aaa/` 目录
4. 拖拽以下文件到 SFTP 窗口:
- `server.py`
- `Index.html`
- `Dockerfile`
- `docker-compose.yml`(修改后的)
- `requirements.txt`
- `.env`
### 4.4 上传 SSL 证书
**创建证书目录:**
```bash
# 在服务器上执行
sudo mkdir -p /etc/ssl/certs/aaa_why_vin
```
**上传证书文件:**
使用 Termius SFTP 将以下文件上传到 `/etc/ssl/certs/aaa_why_vin/`:
- `fullchain.pem`
- `privkey.pem`
**验证证书上传:**
```bash
ls -la /etc/ssl/certs/aaa_why_vin/
# 应该看到 fullchain.pem 和 privkey.pem 两个文件
# 验证证书内容
sudo openssl x509 -in /etc/ssl/certs/aaa_why_vin/fullchain.pem -noout -subject -dates
# 应该显示 subject=CN = aaa.why.vin
# 设置证书文件权限
sudo chmod 644 /etc/ssl/certs/aaa_why_vin/fullchain.pem
sudo chmod 600 /etc/ssl/certs/aaa_why_vin/privkey.pem
```
### 4.5 开放防火墙端口
```bash
# 开放 HTTP 和 HTTPS 端口
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# 如果需要直接访问 8001 端口(可选)
sudo ufw allow 8001/tcp
# 确认规则已添加
sudo ufw status
```
### 4.6 创建 Nginx 配置文件
```bash
# 创建 Nginx 站点配置
sudo nano /etc/nginx/sites-available/aaa.why.vin
```
**粘贴以下配置内容:**
```nginx
server {
listen 80;
server_name aaa.why.vin;
location / {
proxy_pass http://127.0.0.1:8001;
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";
}
}
server {
listen 443 ssl;
server_name aaa.why.vin;
# SSL 证书路径
ssl_certificate /etc/ssl/certs/aaa_why_vin/fullchain.pem;
ssl_certificate_key /etc/ssl/certs/aaa_why_vin/privkey.pem;
# SSL 优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:8001;
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";
}
}
```
保存文件:`Ctrl+X`,然后 `Y`,最后 `Enter`
### 4.7 启用站点配置
```bash
# 创建符号链接启用站点
sudo ln -s /etc/nginx/sites-available/aaa.why.vin /etc/nginx/sites-enabled/
# 测试 Nginx 配置
sudo nginx -t
# 应该显示: syntax is ok 和 test is successful
# 重新加载 Nginx
sudo systemctl reload nginx
# 确认 Nginx 运行状态
sudo systemctl status nginx
```
### 4.8 启动 Docker 容器
```bash
# 进入项目目录
cd /home/ubuntu/gemini-storyboard-aaa
# 创建状态目录
mkdir -p state
# 将用户添加到 docker 组
sudo usermod -aG docker ubuntu
newgrp docker
# 构建并启动容器
docker compose up -d
# 查看容器日志
docker compose logs -f
# 检查容器状态
docker ps | grep gemini-storyboard-aaa
```
---
## 五、验证部署
### 4.1 检查容器状态
```bash
docker ps | grep gemini-storyboard-aaa
# 应该看到容器运行中,端口映射为 0.0.0.0:8001->8000/tcp
```
### 4.2 本地测试
```bash
# 测试应用健康检查
curl http://localhost:8001/healthz
# 应该返回: {"ok":true}
```
### 4.3 外部访问测试
```bash
# 测试 HTTP
curl -s http://aaa.why.vin/healthz
# 应该返回: {"ok":true}
# 测试 HTTPS
curl -s https://aaa.why.vin/healthz
# 应该返回: {"ok":true}(不需要 -k,因为使用正规证书)
```
### 4.4 浏览器访问
在浏览器中打开:
- **HTTP:** http://aaa.why.vin
- **HTTPS:** https://aaa.why.vin
---
## 六、常见问题排查
### 6.1 容器无法启动(两种方案通用)
```bash
# 查看容器日志
cd /home/ubuntu/gemini-storyboard-aaa
docker compose logs
# 检查端口是否被占用
sudo lsof -i :8001
```
### 6.2 端口被占用(两种方案通用)
```bash
# 查找占用 8001 端口的进程
sudo lsof -i :8001
# 停止占用端口的容器
docker stop <容器名或ID>
```
### 6.3 Nginx 配置错误 - 方案 A(有 1Panel)
```bash
# 测试 Nginx 配置
docker exec 1Panel-openresty-D5XG nginx -t
# 查看 Nginx 错误日志
docker exec 1Panel-openresty-D5XG tail -50 /var/log/nginx/error.log
```
### 6.4 Nginx 配置错误 - 方案 B(原生 Nginx)
```bash
# 测试 Nginx 配置
sudo nginx -t
# 查看 Nginx 错误日志
sudo tail -50 /var/log/nginx/error.log
# 查看 Nginx 状态
sudo systemctl status nginx
```
### 6.5 证书问题 - 方案 A(有 1Panel)
```bash
# 验证证书文件
docker exec 1Panel-openresty-D5XG ls -la /www/sites/aaa.why.vin/ssl/
# 检查证书内容
docker exec 1Panel-openresty-D5XG openssl x509 -in /www/sites/aaa.why.vin/ssl/fullchain.pem -noout -subject -dates
```
### 6.6 证书问题 - 方案 B(原生 Nginx)
```bash
# 验证证书文件
ls -la /etc/ssl/certs/aaa_why_vin/
# 检查证书内容
sudo openssl x509 -in /etc/ssl/certs/aaa_why_vin/fullchain.pem -noout -subject -dates
# 检查证书权限
ls -l /etc/ssl/certs/aaa_why_vin/
# fullchain.pem 应该是 644
# privkey.pem 应该是 600
```
### 6.7 外网无法访问(两种方案通用)
```bash
# 检查防火墙
sudo ufw status | grep -E "80|443|8001"
# 如果没有规则,添加
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8001/tcp
```
---
## 七、管理命令
### 7.1 Docker 容器管理(两种方案通用)
```bash
cd /home/ubuntu/gemini-storyboard-aaa
# 查看日志
docker compose logs -f
# 重启服务
docker compose restart
# 停止服务
docker compose down
# 更新代码后重新部署
docker compose down
docker compose up -d --build
# 进入容器调试
docker exec -it gemini-storyboard-aaa bash
```
### 7.2 Nginx 管理 - 方案 A(有 1Panel)
```bash
# 测试配置
docker exec 1Panel-openresty-D5XG nginx -t
# 重新加载配置
docker exec 1Panel-openresty-D5XG nginx -s reload
# 查看 Nginx 日志
docker exec 1Panel-openresty-D5XG tail -f /var/log/nginx/access.log
docker exec 1Panel-openresty-D5XG tail -f /var/log/nginx/error.log
```
### 7.3 Nginx 管理 - 方案 B(原生 Nginx)
```bash
# 测试配置
sudo nginx -t
# 重新加载配置
sudo systemctl reload nginx
# 重启 Nginx
sudo systemctl restart nginx
# 查看 Nginx 状态
sudo systemctl status nginx
# 查看 Nginx 访问日志
sudo tail -f /var/log/nginx/access.log
# 查看 Nginx 错误日志
sudo tail -f /var/log/nginx/error.log
# 停止 Nginx
sudo systemctl stop nginx
# 启动 Nginx
sudo systemctl start nginx
```
### 7.4 证书更新 - 方案 A(有 1Panel)
当证书更新后:
```bash
# 1. 上传新证书到 /www/ssl/aaa_why_vin/
# 2. 复制到容器
docker cp /www/ssl/aaa_why_vin/fullchain.pem 1Panel-openresty-D5XG:/www/sites/aaa.why.vin/ssl/
docker cp /www/ssl/aaa_why_vin/privkey.pem 1Panel-openresty-D5XG:/www/sites/aaa.why.vin/ssl/
# 3. 重新加载 Nginx
docker exec 1Panel-openresty-D5XG nginx -s reload
# 4. 验证 HTTPS 访问
curl -s https://aaa.why.vin/healthz
```
### 7.5 证书更新 - 方案 B(原生 Nginx)
当证书更新后:
```bash
# 1. 上传新证书到 /etc/ssl/certs/aaa_why_vin/
# 2. 验证新证书
sudo openssl x509 -in /etc/ssl/certs/aaa_why_vin/fullchain.pem -noout -subject -dates
# 3. 设置正确权限
sudo chmod 644 /etc/ssl/certs/aaa_why_vin/fullchain.pem
sudo chmod 600 /etc/ssl/certs/aaa_why_vin/privkey.pem
# 4. 重新加载 Nginx
sudo systemctl reload nginx
# 5. 验证 HTTPS 访问
curl -s https://aaa.why.vin/healthz
```
---
## 八、部署后的文件位置总结
### 8.1 方案 A(有 1Panel)
| 文件/目录 | 服务器路径 | 说明 |
|-----------|-----------|------|
| 项目文件 | `/home/ubuntu/gemini-storyboard-aaa/` | 所有应用文件 |
| SSL 证书源 | `/www/ssl/aaa_why_vin/` | 上传的证书文件 |
| SSL 证书容器内 | `/www/sites/aaa.why.vin/ssl/` | Nginx 使用的证书 |
| Nginx 配置 | `/usr/local/openresty/nginx/conf/conf.d/aaa.why.vin.conf` | 网站配置 |
| 状态数据 | `/home/ubuntu/gemini-storyboard-aaa/state/` | 持久化数据 |
### 8.2 方案 B(无 1Panel,原生 Nginx)
| 文件/目录 | 服务器路径 | 说明 |
|-----------|-----------|------|
| 项目文件 | `/home/ubuntu/gemini-storyboard-aaa/` | 所有应用文件 |
| SSL 证书 | `/etc/ssl/certs/aaa_why_vin/` | 证书文件 |
| Nginx 配置 | `/etc/nginx/sites-available/aaa.why.vin` | 网站配置 |
| Nginx 启用链接 | `/etc/nginx/sites-enabled/aaa.why.vin` | 符号链接 |
| Nginx 日志 | `/var/log/nginx/` | 访问和错误日志 |
| 状态数据 | `/home/ubuntu/gemini-storyboard-aaa/state/` | 持久化数据 |
---
## 九、与 test.why.vin 的区别
| 项目 | test.why.vin | aaa.why.vin |
|------|-------------|-------------|
| 容器名 | `gemini-storyboard` | `gemini-storyboard-aaa` |
| 项目目录 | `/home/ubuntu/gemini-storyboard/` | `/home/ubuntu/gemini-storyboard-aaa/` |
| 应用端口 | 8000 | 8001 |
| 域名 | test.why.vin | aaa.why.vin |
**方案 A(有 1Panel):**
| SSL 证书 | `/www/sites/test.why.vin/ssl/` | `/www/sites/aaa.why.vin/ssl/` |
| Nginx 配置 | `test.why.vin.conf` | `aaa.why.vin.conf` |
| 代理目标 | `127.0.0.1:8000` | `127.0.0.1:8001` |
**方案 B(原生 Nginx):**
| SSL 证书 | `/etc/ssl/certs/test_why_vin/` | `/etc/ssl/certs/aaa_why_vin/` |
| Nginx 配置 | `/etc/nginx/sites-available/test.why.vin` | `/etc/nginx/sites-available/aaa.why.vin` |
| 代理目标 | `127.0.0.1:8000` | `127.0.0.1:8001` |
---
## 十、快速检查清单
部署完成后,按以下清单检查:
### 10.1 方案 A(有 1Panel)
- [ ] `docker-compose.yml` 端口已改为 `8001:8000`
- [ ] 容器名已改为 `gemini-storyboard-aaa`
- [ ] SSL 证书已上传到 `/www/ssl/aaa_why_vin/`
- [ ] 防火墙已开放 80、443 端口
- [ ] 容器内 SSL 目录已创建:`/www/sites/aaa.why.vin/ssl/`
- [ ] 证书已复制到容器内
- [ ] Nginx 配置文件已创建并复制到容器
- [ ] Nginx 已重新加载
- [ ] Docker 容器已启动
- [ ] `curl http://localhost:8001/healthz` 返回 `{"ok":true}`
- [ ] `curl https://aaa.why.vin/healthz` 返回 `{"ok":true}`
- [ ] 浏览器可以访问 https://aaa.why.vin
### 10.2 方案 B(原生 Nginx)
- [ ] Nginx 已安装:`nginx -v`
- [ ] `docker-compose.yml` 端口已改为 `8001:8000`
- [ ] 容器名已改为 `gemini-storyboard-aaa`
- [ ] SSL 证书已上传到 `/etc/ssl/certs/aaa_why_vin/`
- [ ] 证书权限正确:`fullchain.pem (644)`, `privkey.pem (600)`
- [ ] 防火墙已开放 80、443 端口
- [ ] Nginx 配置文件已创建:`/etc/nginx/sites-available/aaa.why.vin`
- [ ] 站点已启用:符号链接存在于 `/etc/nginx/sites-enabled/`
- [ ] Nginx 配置测试通过:`sudo nginx -t`
- [ ] Nginx 已重新加载:`sudo systemctl reload nginx`
- [ ] Docker 容器已启动
- [ ] `curl http://localhost:8001/healthz` 返回 `{"ok":true}`
- [ ] `curl https://aaa.why.vin/healthz` 返回 `{"ok":true}`
- [ ] 浏览器可以访问 https://aaa.why.vin
---
**部署完成后,访问地址:https://aaa.why.vin**
Gemini Storyboard 部署指南
_