gcx/frontend/admin-web/DEPLOY.md

289 lines
7.0 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.

# Genex Admin Web 部署指南
## 环境要求
| 依赖 | 最低版本 | 说明 |
|------|---------|------|
| Docker | 20.10+ | 容器运行环境 |
| Docker Compose | v2+ | 容器编排 |
| Nginx | 1.18+ | 反向代理 (SSL 部署时安装) |
| Certbot | 1.0+ | Let's Encrypt 证书管理 (SSL 部署时安装) |
服务器系统: Ubuntu 20.04+ / Debian 11+
## 项目结构
```
frontend/admin-web/
├── deploy.sh # 一键部署脚本
├── Dockerfile # 三阶段 Docker 构建
├── docker-compose.yml # Docker Compose 编排
├── nginx/
│ └── admin.gogenex.cn.conf # Nginx HTTPS 配置模板
├── package.json # Next.js 15 + React 18
├── next.config.ts # Next.js 配置 (standalone 输出)
├── tsconfig.json # TypeScript 配置
└── src/
└── app/ # Next.js App Router
├── layout.tsx # 根布局
├── page.tsx # 首页 (重定向到 /dashboard)
├── providers.tsx # 全局 Providers
├── globals.css # 全局样式
└── api/health/route.ts # 健康检查 API
```
## 快速部署 (3 步)
```bash
# 1. 克隆代码并进入目录
cd frontend/admin-web
# 2. 启动 Docker 容器
./deploy.sh start
# 3. 安装 Nginx + SSL 证书
sudo ./deploy.sh nginx install
```
部署完成后访问: https://admin.gogenex.cn
---
## 详细步骤
### 第一步: 启动 Docker 容器
```bash
./deploy.sh start
```
脚本会自动:
1. 检查 Docker 和 Docker Compose
2. 检测端口占用,停止旧服务
3. 构建三阶段 Docker 镜像 (deps → builder → runner)
4. 启动容器并等待健康检查通过
启动后容器监听 `localhost:3000`,可通过以下方式验证:
```bash
# 查看容器状态
./deploy.sh status
# 验证健康检查
curl http://localhost:3000/api/health
# 返回: {"status":"ok","service":"genex-admin-web","timestamp":"..."}
```
### 第二步: 配置域名 DNS
在域名 DNS 管理中添加 A 记录:
```
admin.gogenex.cn → <服务器公网 IP>
```
确保:
- DNS 已生效 (可用 `dig admin.gogenex.cn` 验证)
- 服务器防火墙已放行 80 和 443 端口
### 第三步: 安装 Nginx + SSL 证书
```bash
sudo ./deploy.sh nginx install
```
脚本自动执行 5 个步骤:
| 步骤 | 操作 | 说明 |
|------|------|------|
| 1/5 | 安装依赖 | 自动安装 nginx 和 certbot (如未安装) |
| 2/5 | HTTP 临时配置 | 部署 HTTP 站点,包含 ACME 验证路径 |
| 3/5 | 申请 SSL 证书 | certbot webroot 方式申请 Let's Encrypt 证书 |
| 4/5 | HTTPS 配置 | 部署完整 HTTPS 配置 (从 `nginx/` 目录读取) |
| 5/5 | 自动续期 | 配置 certbot renew hook证书续期后自动重载 Nginx |
过程中会提示确认 DNS 是否已生效,输入 `y` 继续。
---
## deploy.sh 命令参考
### Docker 命令
```bash
./deploy.sh build # 仅构建 Docker 镜像 (不启动)
./deploy.sh start # 构建并启动服务 (默认命令)
./deploy.sh stop # 停止服务
./deploy.sh restart # 重启服务 (stop + start)
./deploy.sh logs # 查看实时日志 (Ctrl+C 退出)
./deploy.sh status # 查看容器状态
./deploy.sh clean # 清理容器、镜像和卷
```
### Nginx + SSL 命令
```bash
# 一键安装 Nginx + SSL (需要 root)
sudo ./deploy.sh nginx install [域名] [邮箱]
# 仅申请/续期 SSL 证书
sudo ./deploy.sh nginx ssl [域名] [邮箱]
# 查看 Nginx 和证书状态
./deploy.sh nginx status
# 重载 Nginx 配置
sudo ./deploy.sh nginx reload
```
默认域名: `admin.gogenex.cn`,默认邮箱: `admin@gogenex.com`
### 自定义域名部署
如果需要使用其他域名:
```bash
# 1. 复制并修改 Nginx 配置模板
cp nginx/admin.gogenex.cn.conf nginx/myapp.example.com.conf
# 编辑文件,替换所有 admin.gogenex.cn 为新域名
# 2. 使用自定义域名安装
sudo ./deploy.sh nginx install myapp.example.com admin@example.com
```
### 环境变量
```bash
# 修改服务端口 (默认 3000)
PORT=8080 ./deploy.sh start
```
---
## Docker 构建说明
采用三阶段构建优化镜像大小:
```
阶段 1 (deps) - node:20-alpine - 安装 npm 依赖
阶段 2 (builder) - node:20-alpine - 执行 next build
阶段 3 (runner) - node:20-alpine - 仅复制 standalone 产物运行
```
关键配置:
- `next.config.ts``output: 'standalone'` 启用独立输出模式
- 运行时使用非 root 用户 `nextjs:nodejs` (UID/GID 1001)
- 内置 curl 用于 Docker 健康检查
---
## SSL 证书管理
### 证书位置
```
/etc/letsencrypt/live/admin.gogenex.cn/
├── fullchain.pem # 完整证书链
├── privkey.pem # 私钥
├── cert.pem # 服务器证书
└── chain.pem # 中间证书
```
### 自动续期
certbot 安装后自动配置 systemd timer每天检查证书有效期。
证书到期前 30 天自动续期,续期后通过 renew hook 自动重载 Nginx。
```bash
# 查看续期定时器状态
systemctl status certbot.timer
# 手动测试续期 (不实际续期)
sudo certbot renew --dry-run
# 手动续期
sudo certbot renew
```
### 强制重新申请
```bash
sudo certbot certonly --force-renewal \
--webroot --webroot-path=/var/www/certbot \
-d admin.gogenex.cn
sudo systemctl reload nginx
```
---
## Nginx 配置说明
HTTPS 配置 (`nginx/admin.gogenex.cn.conf`) 包含:
| 特性 | 说明 |
|------|------|
| HTTP → HTTPS 重定向 | 所有 80 端口请求 301 跳转到 443 |
| TLS 1.2 / 1.3 | 现代加密协议,禁用旧版本 |
| HSTS | `max-age=63072000` (2年),强制浏览器使用 HTTPS |
| Gzip 压缩 | 压缩 JS/CSS/JSON 等文本资源 |
| 安全响应头 | X-Frame-Options, X-Content-Type-Options, X-XSS-Protection |
| 静态资源长缓存 | `/_next/static/` 缓存 1 年 (文件名含 hash) |
| WebSocket 支持 | 支持 Next.js HMR 和实时功能 |
| 反向代理 | 转发到 `127.0.0.1:3000` (Docker 容器) |
---
## 常见问题
### 端口被占用
```bash
# 查看 3000 端口占用
lsof -i :3000
# 或
ss -tlnp | grep 3000
# deploy.sh start 会自动检测并停止旧服务
```
### Docker 构建失败
```bash
# 清理缓存重新构建
./deploy.sh clean
./deploy.sh start
# 查看构建日志
docker compose build --no-cache 2>&1 | tee build.log
```
### SSL 证书申请失败
常见原因:
1. DNS 未生效 - 用 `dig admin.gogenex.cn` 检查 A 记录
2. 80 端口未放行 - 用 `sudo ufw allow 80` 放行
3. 防火墙/安全组拦截 - 检查云服务商安全组规则
```bash
# 手动测试 ACME 验证路径
echo "test" > /var/www/certbot/.well-known/acme-challenge/test
curl http://admin.gogenex.cn/.well-known/acme-challenge/test
# 应返回 "test"
```
### 查看日志
```bash
# Docker 容器日志
./deploy.sh logs
# Nginx 访问日志
tail -f /var/log/nginx/admin.gogenex.cn.access.log
# Nginx 错误日志
tail -f /var/log/nginx/admin.gogenex.cn.error.log
# Certbot 日志
tail -f /var/log/letsencrypt/letsencrypt.log
```