Files
full-stack-fastapi/deploy-tencent.md
魏风 77846b73ef
All checks were successful
Deploy to Production / deploy (push) Successful in 1m6s
feat: Rename project to SpatialHub, update project names in configuration and documentation, and modify social links.
2026-03-13 12:21:17 +08:00

453 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 部署指南:腾讯云 + 1Panel + OpenResty + Gitea CI/CD
## 目录
1. [架构概览](#1-架构概览)
2. [服务器准备](#2-服务器准备)
3. [配置环境变量](#3-配置环境变量)
4. [创建数据库](#4-创建数据库)
5. [手动首次部署](#5-手动首次部署)
6. [在 1Panel 中配置 OpenResty](#6-在-1panel-中配置-openresty)
7. [DNS 解析配置](#7-dns-解析配置)
8. [配置 Gitea Actions CI/CD](#8-配置-gitea-actions-cicd)
9. [验证部署](#9-验证部署)
10. [日常运维](#10-日常运维)
---
## 1. 架构概览
```
用户浏览器
OpenResty (1Panel 管理, SSL, 端口 80/443)
├── makefire.fun → 127.0.0.1:3001 (Frontend Nginx 容器)
└── api.makefire.fun → 127.0.0.1:8000 (Backend FastAPI 容器)
PostgreSQL (1Panel 已有容器, 1panel-network)
```
**关键设计决策:**
- 后端和前端容器只绑定 `127.0.0.1`,不对外暴露,由 OpenResty 统一反代
- 所有容器加入 `1panel-network`,可直接通过 `postgresql` 主机名访问已有数据库
- 不使用 Traefik用 1Panel 自带的 OpenResty 替代)
- 不启动独立 PostgreSQL 容器(复用已有的)
---
## 2. 服务器准备
### 2.1 创建部署目录
```bash
# SSH 登录服务器后执行
sudo mkdir -p /opt/fastapi-app
sudo chown $USER:$USER /opt/fastapi-app
```
### 2.2 初始化 Git 仓库(在 Gitea 上)
1. 登录 Gitea`http://your-server-ip:3000`
2. 创建新仓库,例如 `spatialhub`
3. 在本地开发机上添加 Gitea 远程仓库:
```bash
cd /Users/weifeng/Workspace/full-stack-fastapi-template
# 添加 Gitea 远程
git remote add gitea http://your-server-ip:3000/your-username/spatialhub.git
# 推送代码
git push gitea main
```
---
## 3. 配置环境变量
### 3.1 在服务器上创建生产环境文件
```bash
cd /opt/fastapi-app
# 复制示例文件(首次需要从代码仓库获取)
cp .env.production.example .env.production
```
### 3.2 修改关键配置
```bash
nano .env.production
```
**必须修改的项:**
```bash
# 生成强随机密钥
SECRET_KEY=$(openssl rand -hex 32)
echo "生成的 SECRET_KEY: $SECRET_KEY"
# 设置强管理员密码
FIRST_SUPERUSER_PASSWORD=你的强密码
```
> ⚠️ `SECRET_KEY` 和 `FIRST_SUPERUSER_PASSWORD` 不能使用默认值 `changethis`,否则生产环境会报错。
---
## 4. 创建数据库
在已有的 PostgreSQL 中为本项目创建专用数据库:
```bash
# 方法一:使用 docker exec
docker exec -it 1Panel-postgresql-bxrK psql -U user_ZPKMQ6 -c "CREATE DATABASE app;"
# 验证数据库是否创建成功
docker exec -it 1Panel-postgresql-bxrK psql -U user_ZPKMQ6 -c "\l" | grep app
```
如果你想创建专用用户(更安全,可选):
```bash
docker exec -it 1Panel-postgresql-bxrK psql -U user_ZPKMQ6 -c "
CREATE USER fastapi_user WITH PASSWORD 'your_strong_password';
GRANT ALL PRIVILEGES ON DATABASE app TO fastapi_user;
ALTER DATABASE app OWNER TO fastapi_user;
"
```
> 如果使用专用用户,记得更新 `.env.production` 中的 `POSTGRES_USER` 和 `POSTGRES_PASSWORD`。
---
## 5. 手动首次部署
### 5.1 克隆代码到服务器
```bash
cd /opt/fastapi-app
git clone http://localhost:3000/your-username/spatialhub.git .
# 或者如果已经有代码
git pull origin main
```
### 5.2 复制环境变量文件
确保 `.env.production``/opt/fastapi-app/` 目录下。
### 5.3 构建和启动
```bash
cd /opt/fastapi-app
# 构建镜像
docker compose -f compose.prod.yml build
# 启动服务
docker compose -f compose.prod.yml up -d
# 查看日志
docker compose -f compose.prod.yml logs -f
```
### 5.4 验证容器状态
```bash
# 查看运行状态
docker compose -f compose.prod.yml ps
# 测试后端
curl http://127.0.0.1:8000/api/v1/utils/health-check/
# 测试前端
curl -I http://127.0.0.1:3001
```
---
## 6. 在 1Panel 中配置 OpenResty
### 6.1 创建前端网站
1. 打开 1Panel → **网站****创建网站**
2. 选择 **反向代理**
3. 配置:
- **主域名**: `makefire.fun`
- **代理地址**: `http://127.0.0.1:3001`
4. 点击创建
### 6.2 创建后端 API 网站
1. **网站****创建网站****反向代理**
2. 配置:
- **主域名**: `api.makefire.fun`
- **代理地址**: `http://127.0.0.1:8000`
3. 点击创建
### 6.3 配置 SSL 证书
对每个网站:
1. 点击网站名称进入设置
2. 选择 **HTTPS** 标签
3. 选择 **申请证书****Let's Encrypt**
4. 勾选 **自动续签**
5. 勾选 **HTTP → HTTPS 强制跳转**
### 6.4 修改后端网站配置(可选优化)
进入 `api.makefire.fun` 网站设置 → **配置文件**,在 `location /` 块中添加:
```nginx
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 请求体大小限制
client_max_body_size 10m;
# 超时
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
```
> 完整参考配置见项目根目录的 `openresty-example.conf`。
---
## 7. DNS 解析配置
在你的域名 DNS 管理处(腾讯云 DNS 或其他)添加:
| 记录类型 | 主机记录 | 记录值 | TTL |
|---------|---------|--------|-----|
| A | @ | 你的服务器 IP | 600 |
| A | api | 你的服务器 IP | 600 |
> 如果使用腾讯云域名,进入 **DNS 解析 DNSPod** 配置。
---
## 8. 配置 Gitea Actions CI/CD
### 8.1 安装 Gitea Actions Runner
```bash
# 1. 下载 Gitea Actions Runner
# 访问 https://gitea.com/gitea/act_runner/releases 获取最新版本
wget https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64
chmod +x act_runner-0.2.11-linux-amd64
sudo mv act_runner-0.2.11-linux-amd64 /usr/local/bin/act_runner
# 2. 生成配置文件
cd /opt
act_runner generate-config > act_runner_config.yaml
```
### 8.2 修改 Runner 配置
编辑 `/opt/act_runner_config.yaml`,关键修改:
```yaml
runner:
# 标签,决定 workflow 中 runs-on 可以匹配的值
labels:
- "ubuntu-latest:host"
# ↑ 使用 host 模式,直接在服务器上运行(不在 Docker 中套 Docker
```
> **为什么用 `host` 模式?** 因为 workflow 需要执行 `docker compose` 命令来管理服务器上的容器。若在容器中运行,需要额外配置 Docker-in-Docker对低内存服务器更加不友好。
### 8.3 注册 Runner
```bash
# 1. 在 Gitea 中获取 Runner Token
# 进入仓库 → Settings → Actions → Runners → 点击 "Create new runner"
# 复制显示的 Token
# 2. 注册
act_runner register \
--instance http://localhost:3000 \
--token YOUR_RUNNER_TOKEN \
--name my-runner \
--labels "ubuntu-latest:host" \
--config /opt/act_runner_config.yaml \
--no-interactive
# 3. 启动(测试)
act_runner daemon --config /opt/act_runner_config.yaml
```
### 8.4 设置为系统服务(推荐)
```bash
sudo tee /etc/systemd/system/gitea-runner.service << 'EOF'
[Unit]
Description=Gitea Actions Runner
After=network.target docker.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/fastapi-app
ExecStart=/usr/local/bin/act_runner daemon --config /opt/act_runner_config.yaml
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable gitea-runner
sudo systemctl start gitea-runner
# 查看状态
sudo systemctl status gitea-runner
```
### 8.5 配置 Gitea Secrets
在 Gitea 仓库中配置环境变量密钥:
1. 进入仓库 → **Settings****Actions****Secrets**
2. 添加以下 Secrets
| Secret 名称 | 值 |
|-------------|-----|
| `DOMAIN` | `makefire.fun` |
| `FRONTEND_HOST` | `https://makefire.fun` |
| `PROJECT_NAME` | `SpatialHub` |
| `STACK_NAME` | `spatialhub` |
| `BACKEND_CORS_ORIGINS` | `https://makefire.fun,https://api.makefire.fun` |
| `SECRET_KEY` | *(用 `openssl rand -hex 32` 生成)* |
| `FIRST_SUPERUSER` | `admin@makefire.fun` |
| `FIRST_SUPERUSER_PASSWORD` | *(你的强密码)* |
| `SMTP_HOST` | *(留空或填写)* |
| `SMTP_USER` | *(留空或填写)* |
| `SMTP_PASSWORD` | *(留空或填写)* |
| `EMAILS_FROM_EMAIL` | `info@makefire.fun` |
| `SMTP_TLS` | `True` |
| `SMTP_SSL` | `False` |
| `SMTP_PORT` | `587` |
| `POSTGRES_SERVER` | `postgresql` |
| `POSTGRES_PORT` | `5432` |
| `POSTGRES_DB` | `app` |
| `POSTGRES_USER` | `user_ZPKMQ6` |
| `POSTGRES_PASSWORD` | `password_CYmsGt` |
| `SENTRY_DSN` | *(留空)* |
| `DOCKER_IMAGE_BACKEND` | `backend` |
| `DOCKER_IMAGE_FRONTEND` | `frontend` |
### 8.6 启用 Gitea Actions
1. 进入仓库 → **Settings****Repository**
2. 确保 **Actions** 功能已启用
3. 如果 Gitea 全局未启用 Actions需要在 Gitea 配置文件中添加:
```ini
; 在 /opt/1panel/apps/gitea/gitea/data/gitea/conf/app.ini 中
[actions]
ENABLED = true
```
修改后重启 Gitea 容器:
```bash
docker restart 1Panel-gitea-FSXv
```
---
## 9. 验证部署
### 9.1 本地访问测试
```bash
# 后端健康检查
curl http://127.0.0.1:8000/api/v1/utils/health-check/
# 前端页面
curl -I http://127.0.0.1:3001
```
### 9.2 域名访问测试
```bash
# 前端
curl -I https://makefire.fun
# 后端 API 文档
curl -I https://api.makefire.fun/docs
# 后端健康检查
curl https://api.makefire.fun/api/v1/utils/health-check/
```
### 9.3 CI/CD 测试
```bash
# 在本地开发机上
cd /Users/weifeng/Workspace/full-stack-fastapi-template
echo "# test" >> README.md
git add .
git commit -m "test: trigger CI/CD"
git push gitea main
```
然后在 Gitea 仓库的 **Actions** 标签中查看运行状态。
---
## 10. 日常运维
### 查看日志
```bash
cd /opt/fastapi-app
docker compose -f compose.prod.yml logs -f backend # 后端日志
docker compose -f compose.prod.yml logs -f frontend # 前端日志
docker compose -f compose.prod.yml logs -f # 全部日志
```
### 重启服务
```bash
docker compose -f compose.prod.yml restart backend
docker compose -f compose.prod.yml restart frontend
```
### 手动重新部署
```bash
cd /opt/fastapi-app
git pull origin main
docker compose -f compose.prod.yml build
docker compose -f compose.prod.yml down
docker compose -f compose.prod.yml up -d
```
### 清理 Docker 资源
```bash
# 清理无用镜像(释放磁盘空间)
docker image prune -f
docker system prune -f
```
### 数据库备份
```bash
# 备份
docker exec 1Panel-postgresql-bxrK pg_dump -U user_ZPKMQ6 app > backup_$(date +%Y%m%d).sql
# 恢复
docker exec -i 1Panel-postgresql-bxrK psql -U user_ZPKMQ6 app < backup_20260311.sql
```