chore: 部署文档不纳入版本管理
- 从 git 移除 qiji部署交接文档.md 和 通用部署文档.md - 更新 .gitignore 忽略所有 *部署文档.md/*部署交接文档.md - 部署文档含敏感信息(服务器IP/端口/密码),应本地保存 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -196,6 +196,10 @@ Thumbs.db
|
||||
# Env
|
||||
.env
|
||||
|
||||
# Deployment docs (contain credentials, not for git)
|
||||
*部署交接文档.md
|
||||
*部署文档.md
|
||||
|
||||
# Claude
|
||||
CLAUDE.md
|
||||
.claude/
|
||||
|
||||
-602
@@ -1,602 +0,0 @@
|
||||
# 企迹 (qiji) 部署交接文档
|
||||
|
||||
## 1. 部署架构总览
|
||||
|
||||
```
|
||||
用户浏览器 → qj.dhdx.fun → 远程服务器(175.178.19.237)
|
||||
│
|
||||
OpenResty (80/443)
|
||||
│
|
||||
┌──────────────┴──────────────┐
|
||||
▼ ▼
|
||||
前端容器 frp 隧道(18061)
|
||||
qiji-frontend │
|
||||
(18063→80) frps 服务端
|
||||
(175.178.19.237)
|
||||
│
|
||||
frp 隧道
|
||||
│
|
||||
frpc 客户端
|
||||
(本机服务器)
|
||||
│
|
||||
┌──────────┴──────────┐
|
||||
▼ ▼
|
||||
FastAPI 后端 Casdoor 认证
|
||||
(8002端口) (18000端口, 共享)
|
||||
│
|
||||
▼
|
||||
PostgreSQL (5432, 共享)
|
||||
MinIO (10.10.10.13:17051)
|
||||
```
|
||||
|
||||
**一句话概括:** 用户访问 `http://qj.dhdx.fun`,OpenResty 将前端 `/` 路由到前端容器(18063),将 `/api/` 路由到 FRP 隧道(18061),frp 将流量转发到本机服务器的 qiji 后端(8002)。Casdoor 和 PostgreSQL 复用已有基础设施。
|
||||
|
||||
> **与 H3ConuMS2 的关系:** qiji 和 H3ConuMS2 共享同一套基础设施(远程服务器、FRP 隧道网格、OpenResty、Casdoor、PostgreSQL),只是各自占用不同的端口和域名。互不干扰。
|
||||
|
||||
---
|
||||
|
||||
## 2. 服务器信息
|
||||
|
||||
### 远程服务器(部署 frps 服务端 + 前端容器 + OpenResty)
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| IP 地址 | 175.178.19.237 |
|
||||
| SSH 端口 | 7072 |
|
||||
| SSH 用户 | root |
|
||||
| SSH 密码 | (见实际交接信息) |
|
||||
| SSH 密钥 | 已安装(本机 → 远程),可直接免密登录 |
|
||||
| 系统 | Ubuntu 22.04 |
|
||||
| 管理面板 | 1Panel (端口 7071) |
|
||||
| 配置 | 2 vCPU, 3.6GB RAM |
|
||||
|
||||
### 本机服务器(部署 frpc + 后端 + 数据库)
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| 角色 | 本地开发/服务机 |
|
||||
| FRP 类型 | frpc 原生进程(非 Docker) |
|
||||
| frpc 配置文件 | `/etc/frp/frpc.toml` |
|
||||
| frpc 管理地址 | http://localhost:7000 (admin / your-frp-password) |
|
||||
| 操作系统 | Ubuntu (带 Docker) |
|
||||
|
||||
---
|
||||
|
||||
## 3. FRP 配置(新增 qiji 隧道)
|
||||
|
||||
### 当前 FRP 状态
|
||||
|
||||
frpc 已在本机以原生进程运行(`/usr/bin/frpc -c /etc/frp/frpc.toml`),所有 7 条隧道正常运行。
|
||||
|
||||
**现有隧道列表(勿动):**
|
||||
|
||||
| 隧道名称 | 本地端口 | 远程端口 | 用途 |
|
||||
|----------|---------|---------|------|
|
||||
| mysql | 3306 | 13306 | MySQL 远程访问 |
|
||||
| postgresql | 5432 | 15432 | PostgreSQL 远程访问 |
|
||||
| redis | 6379 | 16379 | Redis 远程访问 |
|
||||
| gitea-web | 18003 | 18009 | Gitea |
|
||||
| h3conums-v2-backend | 8000 | 18060 | H3ConuMS2 后端 |
|
||||
| casdoor | 18000 | 18010 | Casdoor 认证 |
|
||||
| gx-gp-notify | 18001 | 18011 | 通知服务 |
|
||||
|
||||
### 新增 qiji 后端隧道
|
||||
|
||||
编辑 `/etc/frp/frpc.toml`,在文件末尾添加:
|
||||
|
||||
```toml
|
||||
[[proxies]]
|
||||
name = "qiji-backend"
|
||||
type = "tcp"
|
||||
localIP = "127.0.0.1"
|
||||
localPort = 8002
|
||||
remotePort = 18061
|
||||
transport.useEncryption = true
|
||||
```
|
||||
|
||||
然后重启 frpc:
|
||||
|
||||
```bash
|
||||
# frpc 是原生进程,需要 kill 后重启
|
||||
# 查看当前进程
|
||||
ps aux | grep frpc
|
||||
|
||||
# 重启(二选一)
|
||||
# 方式一:如果通过 systemd 管理
|
||||
sudo systemctl restart frpc
|
||||
|
||||
# 方式二:如果通过 entrypoint 脚本启动
|
||||
sudo kill $(pgrep frpc) && sudo /usr/local/bin/entrypoint.d/20-frpc-start.sh &
|
||||
```
|
||||
|
||||
重启后验证隧道状态:
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:7000/api/status -u admin:your-frp-password | python3 -m json.tool | grep -A5 qiji
|
||||
```
|
||||
|
||||
应显示 `"status": "running"`。
|
||||
|
||||
> ⚠️ **注意:** frpc 使用 host 网络模式(原生进程监听 0.0.0.0),所以 `localIP = "127.0.0.1"` 是安全的——frpc 只连接本机回环地址。
|
||||
|
||||
### frps 服务端(远程,无需修改)
|
||||
|
||||
frps 配置文件在远程 `/opt/1panel/apps/frps/frps/data/frps.toml`,**无需修改**。只要 frpc 请求的 `remotePort` (18061) 没被远程服务器其他服务占用,隧道即可自动建立。
|
||||
|
||||
---
|
||||
|
||||
## 4. 前端部署(远程服务器 Docker 容器)
|
||||
|
||||
### 4.1 构建前端镜像(本机操作)
|
||||
|
||||
前端使用 Vue 3 + Vite 构建,产物由 nginx 托管在 Docker 容器中。
|
||||
|
||||
**项目中的关键文件:**
|
||||
- `frontend/Dockerfile` — 多阶段构建(node:20-alpine 构建 → nginx:alpine 运行)
|
||||
- `frontend/nginx.conf` — nginx 配置(SPA try_files + `/api/` 反向代理)
|
||||
|
||||
**构建前置:** 确保 `frontend/.env.production`(或构建时环境变量)中 Casdoor 配置正确。Casdoor 回调地址应为 `https://qj.dhdx.fun`(或实际域名)。如果没有 `.env.production` 文件,Vite 会使用 `.env` 中的值。
|
||||
|
||||
```bash
|
||||
# 1. 进入前端目录
|
||||
cd /home/v6ole/pyproject/qiji/frontend
|
||||
|
||||
# 2. (可选)创建生产环境变量文件
|
||||
cat > .env.production << 'EOF'
|
||||
VITE_CASDOOR_ENDPOINT=https://casdoor.dhdx.fun
|
||||
VITE_CASDOOR_CLIENT_ID=your-client-id
|
||||
EOF
|
||||
|
||||
# 3. 构建 Docker 镜像
|
||||
docker build -t qiji-frontend:latest .
|
||||
|
||||
# 4. 验证镜像
|
||||
docker images | grep qiji-frontend
|
||||
```
|
||||
|
||||
### 4.2 推送镜像到远程服务器
|
||||
|
||||
```bash
|
||||
# 保存镜像并远程加载
|
||||
docker save qiji-frontend:latest | ssh -p 7072 root@175.178.19.237 "docker load"
|
||||
|
||||
# 验证远程镜像已加载
|
||||
ssh -p 7072 root@175.178.19.237 "docker images | grep qiji-frontend"
|
||||
```
|
||||
|
||||
### 4.3 在远程服务器启动前端容器
|
||||
|
||||
```bash
|
||||
ssh -p 7072 root@175.178.19.237 "
|
||||
# 停止并删除旧容器(如果存在)
|
||||
docker stop qiji-frontend 2>/dev/null
|
||||
docker rm qiji-frontend 2>/dev/null
|
||||
|
||||
# 启动新容器
|
||||
# 容器内部 nginx 监听 80,映射到宿主机 18063
|
||||
docker run -d \
|
||||
--name qiji-frontend \
|
||||
--restart always \
|
||||
-p 18063:80 \
|
||||
qiji-frontend:latest
|
||||
"
|
||||
```
|
||||
|
||||
### 4.4 前端更新流程(日常使用)
|
||||
|
||||
```bash
|
||||
cd /home/v6ole/pyproject/qiji/frontend
|
||||
|
||||
# 1. 修改代码后重新构建镜像
|
||||
docker build -t qiji-frontend:latest .
|
||||
|
||||
# 2. 推送并重启(一键脚本)
|
||||
docker save qiji-frontend:latest | ssh -p 7072 root@175.178.19.237 "docker load && docker stop qiji-frontend && docker rm qiji-frontend && docker run -d --name qiji-frontend --restart always -p 18063:80 qiji-frontend:latest"
|
||||
|
||||
# 3. 验证
|
||||
curl -s http://175.178.19.237:18063/ | head -20
|
||||
```
|
||||
|
||||
### 4.5 查看前端容器日志
|
||||
|
||||
```bash
|
||||
ssh -p 7072 root@175.178.19.237 "docker logs --tail 50 qiji-frontend"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. OpenResty / Nginx 配置(远程服务器)
|
||||
|
||||
### 5.1 新建站点配置
|
||||
|
||||
在远程服务器创建 `/opt/1panel/apps/openresty/openresty/conf/conf.d/qj.dhdx.fun.conf`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
listen 443 ssl http2;
|
||||
server_name qj.dhdx.fun;
|
||||
index index.html;
|
||||
|
||||
# 基础代理头
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $http_connection;
|
||||
|
||||
access_log /www/sites/qj.dhdx.fun/log/access.log main;
|
||||
error_log /www/sites/qj.dhdx.fun/log/error.log;
|
||||
|
||||
# ACME 验证
|
||||
location ^~ /.well-known/acme-challenge {
|
||||
allow all;
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
|
||||
# 安全头
|
||||
add_header Strict-Transport-Security "max-age=31536000";
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# 前端(qiji-frontend 容器,端口 18063)
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:18063;
|
||||
}
|
||||
|
||||
# 后端 API(frp 隧道 → 本机后端 8002)
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:18061;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
proxy_connect_timeout 60s;
|
||||
}
|
||||
|
||||
# HTTP → HTTPS 重定向
|
||||
if ($scheme = http) {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
# SSL 证书(通过 1Panel 申请 Let's Encrypt 或手动上传)
|
||||
ssl_certificate /www/sites/qj.dhdx.fun/ssl/fullchain.pem;
|
||||
ssl_certificate_key /www/sites/qj.dhdx.fun/ssl/privkey.pem;
|
||||
ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1;
|
||||
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
error_page 497 https://$host$request_uri;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 应用配置
|
||||
|
||||
```bash
|
||||
# 方式一:通过 SSH 直接创建配置文件
|
||||
cat << 'EOF' | ssh -p 7072 root@175.178.19.237 "cat > /opt/1panel/apps/openresty/openresty/conf/conf.d/qj.dhdx.fun.conf"
|
||||
# (粘贴上面的完整 nginx 配置)
|
||||
EOF
|
||||
|
||||
# 创建日志目录
|
||||
ssh -p 7072 root@175.178.19.237 "mkdir -p /www/sites/qj.dhdx.fun/log /www/sites/qj.dhdx.fun/ssl"
|
||||
|
||||
# 重载 OpenResty 配置(在 1Panel 面板 → OpenResty → 重载配置)
|
||||
# 或通过命令行
|
||||
ssh -p 7072 root@175.178.19.237 "docker restart openresty"
|
||||
```
|
||||
|
||||
> ⚠️ **注意:** 建议通过 1Panel 面板(http://175.178.19.237:7071)管理 OpenResty 站点配置和 SSL 证书。直接修改配置文件后需要在面板中**重载配置**才能生效。
|
||||
|
||||
### 5.3 DNS 配置
|
||||
|
||||
在域名 DNS 管理后台添加 A 记录:
|
||||
|
||||
| 类型 | 主机记录 | 记录值 |
|
||||
|------|---------|--------|
|
||||
| A | qj | 175.178.19.237 |
|
||||
|
||||
> 域名根据实际情况选择,如 `qj.dhdx.fun`、`qiji.dhdx.fun` 或 `weekly.dhdx.fun`。
|
||||
|
||||
### 5.4 SSL 证书
|
||||
|
||||
**方式一(推荐):** 通过 1Panel 面板为 `qj.dhdx.fun` 申请 Let's Encrypt 免费证书,自动续期。
|
||||
|
||||
**方式二:** 自签名证书(仅测试用,浏览器会报警告)。
|
||||
|
||||
**方式三:** 暂时只使用 HTTP(注释掉 ssl 相关配置行)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 后端服务(本机服务器)
|
||||
|
||||
### 6.1 启动方式
|
||||
|
||||
后端以原生进程运行(不容器化),与 H3ConuMS2 后端部署方式一致。
|
||||
|
||||
```bash
|
||||
cd /home/v6ole/pyproject/qiji/backend
|
||||
|
||||
# 确保 .env 文件配置正确
|
||||
cp .env.example .env
|
||||
# 编辑 .env,填入实际值
|
||||
|
||||
# 启动后端(端口 8002,监听所有网卡)
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8002 --reload
|
||||
# 生产环境去掉 --reload:
|
||||
# uvicorn app.main:app --host 0.0.0.0 --port 8002
|
||||
```
|
||||
|
||||
### 6.2 环境变量关键配置
|
||||
|
||||
| 配置项 | 说明 | 当前值 |
|
||||
|--------|------|--------|
|
||||
| `DATABASE_URL` | PostgreSQL 连接 | `postgresql+asyncpg://postgres:your-db-password@localhost:5432/qiji` |
|
||||
| `CASDOOR_ENDPOINT` | Casdoor 地址 | `http://localhost:18000`(本机直连) |
|
||||
| `CASDOOR_CLIENT_ID` | Casdoor 应用 ID | 与前端一致 |
|
||||
| `CASDOOR_CLIENT_SECRET` | Casdoor 应用 Secret | 保密 |
|
||||
| `MINIO_ENDPOINT` | MinIO 地址 | `10.10.10.13:17051` |
|
||||
| `SECRET_KEY` | JWT 密钥 | 生产环境务必修改 |
|
||||
| `CORS_ORIGINS` | 允许的前端域名 | 添加 `https://qj.dhdx.fun` |
|
||||
|
||||
### 6.3 生产环境 CORS 配置
|
||||
|
||||
确保 `.env` 中 `CORS_ORIGINS` 包含生产域名:
|
||||
|
||||
```env
|
||||
CORS_ORIGINS=["http://localhost:5173","http://localhost:3000","https://qj.dhdx.fun","http://qj.dhdx.fun"]
|
||||
```
|
||||
|
||||
### 6.4 后端更新流程
|
||||
|
||||
```bash
|
||||
cd /home/v6ole/pyproject/qiji/backend
|
||||
|
||||
# 1. 拉取最新代码
|
||||
git pull
|
||||
|
||||
# 2. (如有新增依赖)
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 3. 重启后端进程
|
||||
# 找到并杀掉旧进程
|
||||
pkill -f "uvicorn app.main:app"
|
||||
# 重新启动
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8002 &
|
||||
```
|
||||
|
||||
> 建议使用 `systemd` 管理后端进程(见第 10 节)。
|
||||
|
||||
---
|
||||
|
||||
## 7. MinIO 文件存储(已共享)
|
||||
|
||||
### 7.1 当前状况
|
||||
|
||||
MinIO 部署在 `10.10.10.13:17051`(内网地址),qiji 使用 bucket `qiji-photos`。
|
||||
|
||||
**问题:** 前端通过预签名 URL 直传 MinIO。如果用户从公网(`qj.dhdx.fun`)访问,浏览器收到的预签名 URL 指向 `10.10.10.13:17051`,公网用户无法访问内网地址。
|
||||
|
||||
### 7.2 解决方案(三选一)
|
||||
|
||||
**方案一(推荐):新增 MinIO FRP 隧道**
|
||||
|
||||
在 `/etc/frp/frpc.toml` 中添加:
|
||||
|
||||
```toml
|
||||
[[proxies]]
|
||||
name = "minio"
|
||||
type = "tcp"
|
||||
localIP = "10.10.10.13"
|
||||
localPort = 17051
|
||||
remotePort = 18064
|
||||
transport.useEncryption = true
|
||||
```
|
||||
|
||||
然后在 MinIO 端配置公网地址(或通过环境变量 `MINIO_ENDPOINT=175.178.19.237:18064`),使生成的预签名 URL 指向公网。
|
||||
|
||||
**方案二:后端代理 MinIO 流量**
|
||||
|
||||
在 qiji 后端添加文件代理路由(如 `/api/files/{bucket}/{object}`),前端不直传 MinIO,而是通过后端中转。简单但增加后端带宽压力。
|
||||
|
||||
**方案三:仅限内网使用**
|
||||
|
||||
如果 qiji 用户都在内网(通过 VPN 或内网 IP 访问),当前配置无需修改。
|
||||
|
||||
> **当前建议:** 如果公网用户需要上传/查看照片,选择方案一。如果只在内网使用,暂不处理。
|
||||
|
||||
---
|
||||
|
||||
## 8. Casdoor 认证(共享,已运行)
|
||||
|
||||
qiji 与 H3ConuMS2 共用同一个 Casdoor 实例。
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| 本机端口 | 18000 |
|
||||
| FRP 远程端口 | 18010 |
|
||||
| 外部访问 | `https://casdoor.dhdx.fun`(已有 Nginx 配置) |
|
||||
| Casdoor 应用名 | `qiji-weekly-report` |
|
||||
|
||||
### 配置要点
|
||||
|
||||
1. **Casdoor 回调地址** 必须添加 `https://qj.dhdx.fun/callback`(或实际域名)
|
||||
2. 前端 `.env.production` 中 `VITE_CASDOOR_ENDPOINT` 指向 `https://casdoor.dhdx.fun`
|
||||
3. 后端 `.env` 中 `CASDOOR_ENDPOINT` 指向 `http://localhost:18000`(本机直连,不经 FRP)
|
||||
|
||||
---
|
||||
|
||||
## 9. 数据库(共享,已运行)
|
||||
|
||||
qiji 使用已有的 PostgreSQL 实例,database 名为 `qiji`(与 H3ConuMS2 的 database 分开)。
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| 本机端口 | 5432 |
|
||||
| FRP 远程端口 | 15432 |
|
||||
| Database | `qiji` |
|
||||
| 远程连接 | `postgresql://postgres:your-db-password@175.178.19.237:15432/qiji` |
|
||||
|
||||
---
|
||||
|
||||
## 10. 常见操作速查
|
||||
|
||||
### 查看 FRP 隧道状态
|
||||
|
||||
```bash
|
||||
# 本机 frpc 管理 API
|
||||
curl -s http://localhost:7000/api/status -u admin:your-frp-password | python3 -m json.tool
|
||||
|
||||
# 只看 qiji 隧道
|
||||
curl -s http://localhost:7000/api/status -u admin:your-frp-password | python3 -c "import sys,json; d=json.load(sys.stdin); [print(p['name'],p['status'],p['local_addr'],'→',p['remote_addr']) for p in d.get('tcp',[])]"
|
||||
|
||||
# 远程 frps 管理 API
|
||||
curl -s http://175.178.19.237:18001/api/status -u admin:your-frp-password | python3 -m json.tool
|
||||
```
|
||||
|
||||
### 重启 FRP
|
||||
|
||||
```bash
|
||||
# 本机 frpc(原生进程)
|
||||
sudo kill $(pgrep frpc) && sudo /usr/local/bin/entrypoint.d/20-frpc-start.sh &
|
||||
|
||||
# 远程 frps(Docker 容器)
|
||||
ssh -p 7072 root@175.178.19.237 "docker restart Frps"
|
||||
```
|
||||
|
||||
### 查看前端容器状态
|
||||
|
||||
```bash
|
||||
ssh -p 7072 root@175.178.19.237 "docker ps --filter name=qiji-frontend"
|
||||
ssh -p 7072 root@175.178.19.237 "docker logs --tail 30 qiji-frontend"
|
||||
```
|
||||
|
||||
### 查看后端运行状态
|
||||
|
||||
```bash
|
||||
# 检查后端进程
|
||||
ps aux | grep uvicorn | grep 8002
|
||||
|
||||
# 测试 API 健康
|
||||
curl http://localhost:8002/api/health
|
||||
```
|
||||
|
||||
### 通过 FRP 隧道测试后端
|
||||
|
||||
```bash
|
||||
# 从远程服务器测试 FRP 隧道是否通
|
||||
ssh -p 7072 root@175.178.19.237 "curl -s http://127.0.0.1:18061/api/health"
|
||||
|
||||
# 从公网测试(如果 OpenResty 已配置)
|
||||
curl -s https://qj.dhdx.fun/api/health
|
||||
```
|
||||
|
||||
### 通过 1Panel 管理远程服务器
|
||||
|
||||
- 浏览器访问 `http://175.178.19.237:7071`
|
||||
- 可视化管理:OpenResty 站点配置、SSL 证书申请、Docker 容器启停
|
||||
|
||||
---
|
||||
|
||||
## 11. 端口总览
|
||||
|
||||
### 远程服务器 (175.178.19.237) 端口
|
||||
|
||||
| 端口 | 用途 | 所属项目 |
|
||||
|------|------|---------|
|
||||
| 22 | SSH(通过 7072 映射) | 基础设施 |
|
||||
| 7071 | 1Panel 管理面板 | 基础设施 |
|
||||
| 7072 | SSH(外部访问端口) | 基础设施 |
|
||||
| 80 | HTTP(OpenResty) | 基础设施 |
|
||||
| 443 | HTTPS(OpenResty) | 基础设施 |
|
||||
| 18000 | frps 控制端口 | 基础设施 |
|
||||
| 18001 | frps 管理面板 | 基础设施 |
|
||||
| 18002 | Halo 博客 | 其他 |
|
||||
| 18003 | Speedtest | 其他 |
|
||||
| 18004-18005 | OpenList | 其他 |
|
||||
| 18006 | IP 监测 | 其他 |
|
||||
| 18009 | ← Gitea (frp) | 共享 |
|
||||
| 18010 | ← Casdoor (frp) | 共享 |
|
||||
| 18011 | ← 通知服务 (frp) | 共享 |
|
||||
| 13306 | ← MySQL (frp) | 共享 |
|
||||
| 15432 | ← PostgreSQL (frp) | 共享 |
|
||||
| 16379 | ← Redis (frp) | 共享 |
|
||||
| 18020 | Sun-Panel | 其他 |
|
||||
| 18051 | Bitwarden | 其他 |
|
||||
| 18052 | CookieCloud | 其他 |
|
||||
| 18054 | Bark Server | 其他 |
|
||||
| 18055 | WeChat API | 其他 |
|
||||
| 18060 | ← H3ConuMS2 后端 (frp) | H3ConuMS2 |
|
||||
| **18061** | **← qiji 后端 (frp)** | **qiji (新增)** |
|
||||
| 18062 | H3ConuMS2 前端容器 | H3ConuMS2 |
|
||||
| **18063** | **qiji 前端容器** | **qiji (新增)** |
|
||||
| ~~18064~~ | ~~MinIO (frp)~~ | **qiji (待定)** |
|
||||
|
||||
### 本机服务器端口
|
||||
|
||||
| 端口 | 用途 | 所属项目 |
|
||||
|------|------|---------|
|
||||
| 3306 | MySQL | 共享 |
|
||||
| 5432 | PostgreSQL | 共享 |
|
||||
| 6379 | Redis | 共享 |
|
||||
| 7000 | frpc 管理面板 | 基础设施 |
|
||||
| 8000 | H3ConuMS2 后端 | H3ConuMS2 |
|
||||
| **8002** | **qiji 后端** | **qiji** |
|
||||
| 18000 | Casdoor | 共享 |
|
||||
| 18001 | 通知服务 | 共享 |
|
||||
| 18003 | Gitea | 共享 |
|
||||
|
||||
---
|
||||
|
||||
## 12. 相关项目路径
|
||||
|
||||
| 路径 | 说明 | 所在服务器 |
|
||||
|------|------|-----------|
|
||||
| `/home/v6ole/pyproject/qiji/` | qiji 项目源码 | 本机 |
|
||||
| `/home/v6ole/pyproject/qiji/backend/` | 后端源码 | 本机 |
|
||||
| `/home/v6ole/pyproject/qiji/frontend/` | 前端源码 | 本机 |
|
||||
| `/home/v6ole/pyproject/qiji/frontend/Dockerfile` | 前端镜像构建文件 | 本机 |
|
||||
| `/home/v6ole/pyproject/qiji/frontend/nginx.conf` | 前端 nginx 配置 | 本机 |
|
||||
| `/home/v6ole/pyproject/qiji/backend/.env` | 后端环境变量(不提交 git) | 本机 |
|
||||
| `/etc/frp/frpc.toml` | frpc 配置(含 qiji 隧道) | 本机 |
|
||||
| `/opt/1panel/apps/frps/frps/data/frps.toml` | frps 配置 | 远程 |
|
||||
| `/opt/1panel/apps/openresty/openresty/conf/conf.d/qj.dhdx.fun.conf` | qiji 站点 Nginx 配置 | 远程 |
|
||||
| `/opt/1panel/apps/openresty/openresty/www/sites/qj.dhdx.fun/ssl/` | qiji SSL 证书 | 远程 |
|
||||
| `/home/v6ole/pyproject/qiji/qiji部署交接文档.md` | 本文档 | 本机 |
|
||||
|
||||
---
|
||||
|
||||
## 13. 部署检查清单
|
||||
|
||||
初次部署时,按以下顺序逐项确认:
|
||||
|
||||
- [ ] **后端**:`.env` 配置正确,`uvicorn` 启动在 8002 端口,`curl localhost:8002/api/health` 正常
|
||||
- [ ] **FRP 隧道**:`/etc/frp/frpc.toml` 添加 `qiji-backend` 隧道,重启 frpc 后状态为 `running`
|
||||
- [ ] **FRP 验证**:从远程 `curl 127.0.0.1:18061/api/health` 能访问后端
|
||||
- [ ] **前端镜像**:`docker build -t qiji-frontend:latest .` 构建成功
|
||||
- [ ] **前端部署**:推送镜像到远程,容器运行在 18063 端口,`curl 175.178.19.237:18063/` 返回 HTML
|
||||
- [ ] **OpenResty**:创建 `qj.dhdx.fun.conf`,重载配置
|
||||
- [ ] **DNS**:添加 A 记录 `qj → 175.178.19.237`
|
||||
- [ ] **SSL**:通过 1Panel 申请 Let's Encrypt 证书(或自签名测试)
|
||||
- [ ] **Casdoor**:确认回调地址添加 `https://qj.dhdx.fun/callback`
|
||||
- [ ] **端到端**:浏览器访问 `https://qj.dhdx.fun`,登录→填报→查看周报全流程通过
|
||||
- [ ] **MinIO**:确认照片上传/查看功能正常(如果公网用户需要,配置 MinIO 隧道)
|
||||
|
||||
---
|
||||
|
||||
## 14. 故障排查
|
||||
|
||||
| 现象 | 检查项 |
|
||||
|------|--------|
|
||||
| 页面打不开 | 远程前端容器是否运行:`docker ps \| grep qiji-frontend` |
|
||||
| 页面打开但 API 报错 | FRP 隧道是否正常:`curl localhost:7000/api/status -u admin:your-frp-password` |
|
||||
| API 返回 500 | 后端进程是否存活:`ps aux \| grep uvicorn \| grep 8002` |
|
||||
| 登录回调失败 | Casdoor 回调地址是否包含生产域名;前端 `.env.production` 中 Casdoor 地址是否正确 |
|
||||
| 照片上传失败 | MinIO 是否可达;预签名 URL 域名是否为公网可访问地址 |
|
||||
| FRP 隧道状态不是 running | frpc 日志:`journalctl -u frpc -f` 或 `dmesg \| grep frpc` |
|
||||
|
||||
> 文档创建日期:2026年6月26日
|
||||
@@ -1,520 +0,0 @@
|
||||
# 项目部署通用文档(FRP + OpenResty + Docker 平台)
|
||||
|
||||
> **用途:** 本机开发 → 远程服务器(175.178.19.237) 的标准化部署方案。每个新项目复制此文档,填入具体端口和域名即可。
|
||||
>
|
||||
> **最后更新:** 2026-06-26
|
||||
|
||||
---
|
||||
|
||||
## 0. 端口规划与分配表
|
||||
|
||||
### 0.1 分配规则
|
||||
|
||||
| 资源 | 端口范围 | 数量 | 说明 |
|
||||
|------|---------|------|------|
|
||||
| 基础设施 | 18000–18019 | 20 | frp / Casdoor / DB 隧道等 |
|
||||
| 杂项服务 | 18020–18049 | 30 | Sun-Panel / Bitwarden 等 |
|
||||
| 项目后端 (frp) | 18060–18079 | 20 | 每个项目占用 1 个 |
|
||||
| 项目前端 (容器) | 18080–18099 | 20 | 每个项目占用 1 个 |
|
||||
| 预留 | 18100–18199 | 100 | 未来扩展 |
|
||||
|
||||
> **新项目默认分配:** 后端 frp 取 18060–18079 中最小可用端口,前端容器取 18080–18099 中最小可用端口。
|
||||
|
||||
### 0.2 当前占用表
|
||||
|
||||
#### 基础设施 & 共享服务 (18000–18019)
|
||||
|
||||
| 端口 | 资源 | 类型 | 说明 |
|
||||
|------|------|------|------|
|
||||
| 18000 | frps 控制 | 基础设施 | FRP 服务端控制端口 |
|
||||
| 18001 | frps 管理面板 | 基础设施 | frps dashboard |
|
||||
| 18002 | Halo | 其他 | 博客 |
|
||||
| 18003 | Speedtest | 其他 | 网速测试 |
|
||||
| 18004 | OpenList | 其他 | 播放列表 |
|
||||
| 18005 | OpenList | 其他 | 播放列表 |
|
||||
| 18006 | IP 监测 | 其他 | 公网 IP 变更监测 |
|
||||
| 18009 | Gitea (frp) | 共享 | Git 仓库 |
|
||||
| 18010 | Casdoor (frp) | 共享 | 统一认证 |
|
||||
| 18011 | 通知服务 (frp) | 共享 | 消息推送 |
|
||||
| 13306 | MySQL (frp) | 共享 | 数据库远程访问 |
|
||||
| 15432 | PostgreSQL (frp) | 共享 | 数据库远程访问 |
|
||||
| 16379 | Redis (frp) | 共享 | 缓存远程访问 |
|
||||
|
||||
#### 杂项服务 (18020–18049)
|
||||
|
||||
| 端口 | 资源 | 说明 |
|
||||
|------|------|------|
|
||||
| 18020 | Sun-Panel | 导航面板 |
|
||||
| 18051 | Bitwarden | 密码管理 |
|
||||
| 18052 | CookieCloud | Cookie 同步 |
|
||||
| 18054 | Bark Server | iOS 推送 |
|
||||
| 18055 | WeChat API | 微信 API 服务 |
|
||||
|
||||
#### 项目后端 (frp 隧道, 18060–18079)
|
||||
|
||||
| 远程端口 | 本机端口 | 项目 | 隧道名称 | 状态 |
|
||||
|---------|---------|------|---------|------|
|
||||
| 18060 | 8000 | H3ConuMS2 | h3conums-v2-backend | ✅ 运行中 |
|
||||
| 18061 | 8002 | 企迹 (qiji) | qiji-backend | ⬜ 待部署 |
|
||||
| 18062 | — | **可用** | — | — |
|
||||
| 18063 | — | **可用** | — | — |
|
||||
| 18064 | — | **可用** | — | — |
|
||||
| 18065 | — | **可用** | — | — |
|
||||
| 18066 | — | **可用** | — | — |
|
||||
| 18067 | — | **可用** | — | — |
|
||||
| 18068 | — | **可用** | — | — |
|
||||
| 18069 | — | **可用** | — | — |
|
||||
| 18070 | — | **可用** | — | — |
|
||||
| 18071 | — | **可用** | — | — |
|
||||
| 18072 | — | **可用** | — | — |
|
||||
| 18073 | — | **可用** | — | — |
|
||||
| 18074 | — | **可用** | — | — |
|
||||
| 18075 | — | **可用** | — | — |
|
||||
| 18076 | — | **可用** | — | — |
|
||||
| 18077 | — | **可用** | — | — |
|
||||
| 18078 | — | **可用** | — | — |
|
||||
| 18079 | — | **可用** | — | — |
|
||||
|
||||
#### 项目前端 (Docker 容器, 18080–18099)
|
||||
|
||||
| 远程端口 | 容器名 | 项目 | 状态 |
|
||||
|---------|--------|------|------|
|
||||
| 18062 | h3conums2-frontend | H3ConuMS2 (legacy) | ✅ 运行中 |
|
||||
| 18063 | qiji-frontend | 企迹 (qiji) | ⬜ 待部署 |
|
||||
| 18080 | — | **可用** | — |
|
||||
| 18081 | — | **可用** | — |
|
||||
| 18082 | — | **可用** | — |
|
||||
| 18083 | — | **可用** | — |
|
||||
| 18084 | — | **可用** | — |
|
||||
| 18085 | — | **可用** | — |
|
||||
| 18086 | — | **可用** | — |
|
||||
| 18087 | — | **可用** | — |
|
||||
| 18088 | — | **可用** | — |
|
||||
| 18089 | — | **可用** | — |
|
||||
| 18090 | — | **可用** | — |
|
||||
| 18091 | — | **可用** | — |
|
||||
| 18092 | — | **可用** | — |
|
||||
| 18093 | — | **可用** | — |
|
||||
| 18094 | — | **可用** | — |
|
||||
| 18095 | — | **可用** | — |
|
||||
| 18096 | — | **可用** | — |
|
||||
| 18097 | — | **可用** | — |
|
||||
| 18098 | — | **可用** | — |
|
||||
| 18099 | — | **可用** | — |
|
||||
|
||||
> ⚠️ **注意:** H3ConuMS2 前端用了 18062(属于后端范围),是历史遗留。新项目严格按范围分配:后端 frp 取 18060–18079,前端容器取 18080–18099。
|
||||
|
||||
### 0.3 本机端口占用
|
||||
|
||||
| 本机端口 | 服务 | 项目 |
|
||||
|---------|------|------|
|
||||
| 3306 | MySQL | 共享 |
|
||||
| 5432 | PostgreSQL | 共享 |
|
||||
| 6379 | Redis | 共享 |
|
||||
| 7000 | frpc 管理面板 | 基础设施 |
|
||||
| 8000 | FastAPI 后端 | H3ConuMS2 |
|
||||
| 8002 | FastAPI 后端 | 企迹 (qiji) |
|
||||
| **8004** | — **可用** | — |
|
||||
| **8006** | — **可用** | — |
|
||||
| **8008** | — **可用** | — |
|
||||
| 18000 | Casdoor | 共享 |
|
||||
| 18001 | 通知服务 | 共享 |
|
||||
| 18003 | Gitea | 共享 |
|
||||
|
||||
> **本机后端端口规划:** 新项目从 8004 开始,每次 +2(8004, 8006, 8008, ...),与 FRP 远程端口(18064, 18066, 18068, ...)保持对应关系,便于记忆。
|
||||
|
||||
---
|
||||
|
||||
## 1. 部署架构总览
|
||||
|
||||
```
|
||||
用户浏览器 → {DOMAIN} → 远程服务器(175.178.19.237)
|
||||
│
|
||||
OpenResty (80/443)
|
||||
│
|
||||
┌──────────────┴──────────────┐
|
||||
▼ ▼
|
||||
前端容器 frp 隧道
|
||||
{FRONTEND_CONTAINER} ({FRP_REMOTE_PORT})
|
||||
(端口映射到宿主机) │
|
||||
frps 服务端
|
||||
(175.178.19.237)
|
||||
│
|
||||
frp 隧道
|
||||
│
|
||||
frpc 客户端
|
||||
(本机服务器)
|
||||
│
|
||||
┌───────────┴───────────┐
|
||||
▼ ▼
|
||||
FastAPI 后端 Casdoor 认证
|
||||
({BACKEND_PORT}) (18000, 共享)
|
||||
│
|
||||
▼
|
||||
PostgreSQL (5432, 共享)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 服务器信息
|
||||
|
||||
### 远程服务器(部署 frps + 前端容器 + OpenResty)
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| IP 地址 | 175.178.19.237 |
|
||||
| SSH 端口 | 7072 |
|
||||
| SSH 用户 | root |
|
||||
| SSH 方式 | 本机已配置免密登录 |
|
||||
| 系统 | Ubuntu 22.04 |
|
||||
| 管理面板 | 1Panel (http://175.178.19.237:7071) |
|
||||
| Web 服务器 | OpenResty (1panel/openresty) |
|
||||
| FRP 服务端 | frps (snowdreamtech/frps:0.69.1, host 网络) |
|
||||
| frps 配置路径 | `/opt/1panel/apps/frps/frps/data/frps.toml` |
|
||||
| OpenResty 站点配置 | `/opt/1panel/apps/openresty/openresty/conf/conf.d/` |
|
||||
|
||||
### 本机服务器(部署 frpc + 后端 + 数据库)
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| 角色 | 本地开发/服务机 |
|
||||
| FRP 类型 | frpc 原生进程(非 Docker) |
|
||||
| frpc 配置文件 | `/etc/frp/frpc.toml` |
|
||||
| frpc 管理 API | http://localhost:7000 (admin / 见实际配置) |
|
||||
| frpc 进程 | `/usr/bin/frpc -c /etc/frp/frpc.toml` |
|
||||
| Casdoor | localhost:18000(原生进程) |
|
||||
| PostgreSQL | localhost:5432 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 新项目部署流程
|
||||
|
||||
### 3.1 第一步:分配端口
|
||||
|
||||
从 [0.2 端口占用表](#02-当前占用表) 中选取最小可用端口,记录在此:
|
||||
|
||||
| 配置项 | 值 | 说明 |
|
||||
|--------|-----|------|
|
||||
| `PROJECT_NAME` | `_________` | 项目名称(英文短名,用于容器名和隧道名) |
|
||||
| `DOMAIN` | `_________` | 域名(需配置 DNS) |
|
||||
| `BACKEND_PORT` | `_________` | 本机后端端口(如 8004) |
|
||||
| `FRP_REMOTE_PORT` | `_________` | FRP 隧道远程端口(从 18060–18079 选) |
|
||||
| `FRONTEND_CONTAINER_PORT` | `_________` | 前端容器宿主机端口(从 18080–18099 选) |
|
||||
| `FRP_TUNNEL_NAME` | `_________` | FRP 隧道名称(如 `xxx-backend`) |
|
||||
| `CONTAINER_NAME` | `_________` | 前端容器名(如 `xxx-frontend`) |
|
||||
|
||||
> 分配后请更新本文档的 [0.2 端口占用表](#02-当前占用表),标记为已占用。
|
||||
|
||||
### 3.2 第二步:添加 FRP 隧道
|
||||
|
||||
编辑 `/etc/frp/frpc.toml`,在末尾添加:
|
||||
|
||||
```toml
|
||||
[[proxies]]
|
||||
name = "{FRP_TUNNEL_NAME}"
|
||||
type = "tcp"
|
||||
localIP = "127.0.0.1"
|
||||
localPort = {BACKEND_PORT}
|
||||
remotePort = {FRP_REMOTE_PORT}
|
||||
transport.useEncryption = true
|
||||
```
|
||||
|
||||
重启 frpc:
|
||||
|
||||
```bash
|
||||
# frpc 是原生进程,kill 后自动重启(由 entrypoint 脚本守护)
|
||||
sudo kill $(pgrep frpc) && sudo /usr/local/bin/entrypoint.d/20-frpc-start.sh &
|
||||
```
|
||||
|
||||
验证隧道:
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:7000/api/status -u admin:{FRP_PASSWORD} | python3 -m json.tool | grep {FRP_TUNNEL_NAME}
|
||||
# 应显示 "status": "running"
|
||||
```
|
||||
|
||||
### 3.3 第三步:配置后端
|
||||
|
||||
确保后端 `.env` 中:
|
||||
|
||||
```env
|
||||
CORS_ORIGINS=["http://localhost:5173","https://{DOMAIN}","http://{DOMAIN}"]
|
||||
CASDOOR_ENDPOINT=http://localhost:18000
|
||||
```
|
||||
|
||||
启动后端:
|
||||
|
||||
```bash
|
||||
cd /home/v6ole/pyproject/{PROJECT_NAME}/backend
|
||||
uvicorn app.main:app --host 0.0.0.0 --port {BACKEND_PORT} &
|
||||
```
|
||||
|
||||
### 3.4 第四步:构建并部署前端
|
||||
|
||||
前端需要有 `Dockerfile`(多阶段构建:node 构建 + nginx 运行)和 `nginx.conf`。
|
||||
|
||||
```bash
|
||||
# 1. 构建镜像
|
||||
cd /home/v6ole/pyproject/{PROJECT_NAME}/frontend
|
||||
docker build -t {CONTAINER_NAME}:latest .
|
||||
|
||||
# 2. 推送到远程
|
||||
docker save {CONTAINER_NAME}:latest | ssh -p 7072 root@175.178.19.237 "docker load"
|
||||
|
||||
# 3. 启动容器
|
||||
ssh -p 7072 root@175.178.19.237 "
|
||||
docker stop {CONTAINER_NAME} 2>/dev/null
|
||||
docker rm {CONTAINER_NAME} 2>/dev/null
|
||||
docker run -d \
|
||||
--name {CONTAINER_NAME} \
|
||||
--restart always \
|
||||
-p {FRONTEND_CONTAINER_PORT}:80 \
|
||||
{CONTAINER_NAME}:latest
|
||||
"
|
||||
|
||||
# 4. 验证
|
||||
curl -s http://175.178.19.237:{FRONTEND_CONTAINER_PORT}/ | head -5
|
||||
```
|
||||
|
||||
### 3.5 第五步:配置 OpenResty
|
||||
|
||||
在远程创建 `/opt/1panel/apps/openresty/openresty/conf/conf.d/{DOMAIN}.conf`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
listen 443 ssl http2;
|
||||
server_name {DOMAIN};
|
||||
index index.html;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $http_connection;
|
||||
|
||||
access_log /www/sites/{DOMAIN}/log/access.log main;
|
||||
error_log /www/sites/{DOMAIN}/log/error.log;
|
||||
|
||||
# ACME 验证
|
||||
location ^~ /.well-known/acme-challenge {
|
||||
allow all;
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
|
||||
# 安全头
|
||||
add_header Strict-Transport-Security "max-age=31536000";
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# 前端
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:{FRONTEND_CONTAINER_PORT};
|
||||
}
|
||||
|
||||
# 后端 API
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:{FRP_REMOTE_PORT};
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
proxy_connect_timeout 60s;
|
||||
}
|
||||
|
||||
# HTTP → HTTPS
|
||||
if ($scheme = http) {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
# SSL(通过 1Panel 申请 Let's Encrypt)
|
||||
ssl_certificate /www/sites/{DOMAIN}/ssl/fullchain.pem;
|
||||
ssl_certificate_key /www/sites/{DOMAIN}/ssl/privkey.pem;
|
||||
ssl_protocols TLSv1.3 TLSv1.2;
|
||||
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
error_page 497 https://$host$request_uri;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
}
|
||||
```
|
||||
|
||||
应用配置:
|
||||
|
||||
```bash
|
||||
# 创建日志和 SSL 目录
|
||||
ssh -p 7072 root@175.178.19.237 "mkdir -p /www/sites/{DOMAIN}/log /www/sites/{DOMAIN}/ssl"
|
||||
|
||||
# 上传配置文件
|
||||
scp -P 7072 /path/to/{DOMAIN}.conf root@175.178.19.237:/opt/1panel/apps/openresty/openresty/conf/conf.d/
|
||||
|
||||
# 重载 OpenResty(在 1Panel 面板操作,或命令行)
|
||||
ssh -p 7072 root@175.178.19.237 "docker restart openresty"
|
||||
```
|
||||
|
||||
### 3.6 第六步:配置 DNS + SSL
|
||||
|
||||
1. **DNS:** 在域名管理后台添加 A 记录 `{DOMAIN}` → `175.178.19.237`
|
||||
2. **SSL:** 通过 1Panel 面板为 `{DOMAIN}` 申请 Let's Encrypt 证书
|
||||
3. **Casdoor:** 在 Casdoor 应用中添加回调地址 `https://{DOMAIN}/callback`
|
||||
|
||||
### 3.7 第七步:验证
|
||||
|
||||
按顺序检查:
|
||||
|
||||
- [ ] 后端进程:`ps aux | grep uvicorn | grep {BACKEND_PORT}`
|
||||
- [ ] 本机 API:`curl http://localhost:{BACKEND_PORT}/api/health`
|
||||
- [ ] FRP 隧道:管理 API 中状态为 `running`
|
||||
- [ ] 远程 API:`ssh -p 7072 root@175.178.19.237 "curl -s http://127.0.0.1:{FRP_REMOTE_PORT}/api/health"`
|
||||
- [ ] 前端容器:`ssh -p 7072 root@175.178.19.237 "docker ps | grep {CONTAINER_NAME}"`
|
||||
- [ ] 前端页面:`curl -s http://175.178.19.237:{FRONTEND_CONTAINER_PORT}/ | head -3`
|
||||
- [ ] OpenResty:`curl -s https://{DOMAIN}/api/health`
|
||||
- [ ] 完整流程:浏览器访问 `https://{DOMAIN}` → 登录 → 功能验证
|
||||
|
||||
---
|
||||
|
||||
## 4. 前端 Dockerfile 模板
|
||||
|
||||
```dockerfile
|
||||
FROM node:20-alpine AS build
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
```
|
||||
|
||||
> **nginx.conf 说明:** 容器内 nginx 只需处理静态文件 SPA fallback。API 代理由边缘 OpenResty 负责,容器内不需要 `/api/` 代理配置。如需容器独立运行(非本平台),保留 `/api/` 代理指向 `backend` 容器名。
|
||||
|
||||
### 极简 nginx.conf(平台部署用)
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# 可选:健康检查
|
||||
location /health {
|
||||
return 200 "ok";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 日常运维速查
|
||||
|
||||
### 5.1 FRP 管理
|
||||
|
||||
```bash
|
||||
# 查看所有隧道状态
|
||||
curl -s http://localhost:7000/api/status -u admin:{FRP_PASSWORD} | python3 -c "
|
||||
import sys,json
|
||||
d=json.load(sys.stdin)
|
||||
for p in d.get('tcp',[]):
|
||||
print(f\"{p['name']:30s} {p['status']:8s} {p['local_addr']:20s} → {p['remote_addr']}\")
|
||||
"
|
||||
|
||||
# 重启 frpc
|
||||
sudo kill $(pgrep frpc) && sudo /usr/local/bin/entrypoint.d/20-frpc-start.sh &
|
||||
|
||||
# 远程 frps 日志
|
||||
ssh -p 7072 root@175.178.19.237 "docker logs --tail 20 Frps"
|
||||
```
|
||||
|
||||
### 5.2 前端容器管理
|
||||
|
||||
```bash
|
||||
# 列出所有前端容器
|
||||
ssh -p 7072 root@175.178.19.237 "docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}'"
|
||||
|
||||
# 更新前端(构建→推送→重启)
|
||||
cd /home/v6ole/pyproject/{PROJECT_NAME}/frontend
|
||||
docker build -t {CONTAINER_NAME}:latest . && \
|
||||
docker save {CONTAINER_NAME}:latest | ssh -p 7072 root@175.178.19.237 \
|
||||
"docker load && docker stop {CONTAINER_NAME} && docker rm {CONTAINER_NAME} && docker run -d --name {CONTAINER_NAME} --restart always -p {FRONTEND_CONTAINER_PORT}:80 {CONTAINER_NAME}:latest"
|
||||
|
||||
# 查看日志
|
||||
ssh -p 7072 root@175.178.19.237 "docker logs --tail 50 {CONTAINER_NAME}"
|
||||
```
|
||||
|
||||
### 5.3 OpenResty 管理
|
||||
|
||||
```bash
|
||||
# 检查配置语法
|
||||
ssh -p 7072 root@175.178.19.237 "docker exec openresty nginx -t"
|
||||
|
||||
# 重载配置(推荐通过 1Panel 面板操作)
|
||||
ssh -p 7072 root@175.178.19.237 "docker restart openresty"
|
||||
|
||||
# 查看访问日志
|
||||
ssh -p 7072 root@175.178.19.237 "tail -50 /www/sites/{DOMAIN}/log/access.log"
|
||||
```
|
||||
|
||||
### 5.4 后端管理
|
||||
|
||||
```bash
|
||||
# 查看所有后端进程
|
||||
ps aux | grep uvicorn | grep -v grep
|
||||
|
||||
# 重启后端
|
||||
pkill -f "uvicorn app.main:app.*{BACKEND_PORT}"
|
||||
cd /home/v6ole/pyproject/{PROJECT_NAME}/backend && uvicorn app.main:app --host 0.0.0.0 --port {BACKEND_PORT} &
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 故障排查
|
||||
|
||||
| 现象 | 检查项 |
|
||||
|------|--------|
|
||||
| 页面 502/504 | OpenResty 代理目标可达?前端容器运行?FRP 隧道正常? |
|
||||
| API 无响应 | `curl localhost:{BACKEND_PORT}/api/health` 本机是否通?FRP 隧道状态? |
|
||||
| 登录/回调失败 | Casdoor 回调地址是否包含 `https://{DOMAIN}/callback`?前端环境变量 Casdoor 地址是否正确? |
|
||||
| 静态资源 404 | 前端构建是否成功?nginx try_files 配置是否正确? |
|
||||
| FRP 隧道 offline | frpc 进程是否存活?远程端口是否被占用?网络是否可达? |
|
||||
| SSL 证书错误 | 证书是否过期?1Panel 自动续期是否正常? |
|
||||
| CORS 报错 | 后端 `CORS_ORIGINS` 是否包含生产域名? |
|
||||
|
||||
---
|
||||
|
||||
## 7. 已有项目索引
|
||||
|
||||
| 项目 | 域名 | 后端(本机) | FRP(远程) | 前端(远程) | 文档 |
|
||||
|------|------|-----------|----------|-----------|------|
|
||||
| H3ConuMS2 | onu.dhdx.fun | 8000 | 18060 | 18062 | H3ConuMS2部署交接文档.md |
|
||||
| 企迹 (qiji) | qj.dhdx.fun | 8002 | 18061 | 18063 | qiji部署交接文档.md |
|
||||
|
||||
---
|
||||
|
||||
## 8. 关键注意事项
|
||||
|
||||
1. **frpc 是原生进程**:修改 `/etc/frp/frpc.toml` 后需手动 kill + 重启,不能用 `systemctl`
|
||||
2. **frps 是 Docker 容器**:远程 frps 配置在容器内,重启容器即生效
|
||||
3. **OpenResty 由 1Panel 管理**:直接改配置文件后需在面板中重载,或重启 openresty 容器
|
||||
4. **端口不可冲突**:分配新端口前务必检查 [0.2 端口占用表](#02-当前占用表)
|
||||
5. **分配后更新本文档**:每次新增项目,更新端口占用表和项目索引
|
||||
6. **Casdoor 共享**:所有项目共用同一个 Casdoor 实例(本机 18000)
|
||||
7. **数据库隔离**:不同项目使用同一 PostgreSQL 实例的不同 database
|
||||
8. **frp 认证 token** 在 frpc 和 frps 两端必须一致
|
||||
9. **所有 frp 隧道已启用加密传输**(`transport.useEncryption = true`)
|
||||
10. **MinIO** 在内网 `10.10.10.13:17051`,公网项目如需文件上传/查看,需要额外配置 frp 隧道或后端代理
|
||||
|
||||
---
|
||||
|
||||
> **模板使用说明:** 新项目部署时复制此文档,将 `{PROJECT_NAME}`、`{DOMAIN}`、`{BACKEND_PORT}`、`{FRP_REMOTE_PORT}`、`{FRONTEND_CONTAINER_PORT}`、`{FRP_TUNNEL_NAME}`、`{CONTAINER_NAME}` 替换为实际值,然后按第三章流程操作。
|
||||
Reference in New Issue
Block a user