Files
2026-09-16 11:09:03 +08:00

134 lines
5.6 KiB
Markdown
Raw Permalink 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 + Docker Compose)
面向 1Panel 用户的生产部署。产物为 `docker compose` 两个服务:`web`(Django + gunicorn)与 `nginx`(admin SPA / SDK 静态 + API 反代),数据库复用 1Panel 已装的 MySQL。
## 1. 前置构建(仓库内完成,产出 dist 与 xdb)
```bash
# 管理后台:产出 admin/dist/
cd admin && pnpm install && pnpm build && cd ..
# 采集 SDK:产出 sdk/dist/v1.js
cd sdk && pnpm install && pnpm build && cd ..
```
下载 ip2region 离线库到 `deploy/data/ip2region.xdb`(compose 以只读卷挂载进容器,重建容器不丢):
- GitHub:https://github.com/lionsoul2014/ip2region (`data/ip2region_v4.xdb`)
- 大陆备用:https://gitee.com/lionsoul/ip2region (同名路径)
```bash
mkdir -p deploy/data
cp /path/to/ip2region_v4.xdb deploy/data/ip2region.xdb
```
## 2. MySQL 准备(1Panel 已有容器)
在 1Panel 的 MySQL 里建库建账号(utf8mb4):
```sql
CREATE DATABASE tracker CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'tracker'@'%' IDENTIFIED BY '<强密码>';
GRANT ALL PRIVILEGES ON tracker.* TO 'tracker'@'%';
FLUSH PRIVILEGES;
```
**容器连宿主 MySQL 的三条路径**(`.env` 的 `DB_HOST` 三选一):
| 路径 | 做法 | DB_HOST | 备注 |
|---|---|---|---|
| a | 走宿主机发布端口(compose 已配 `extra_hosts: host.docker.internal:host-gateway`) | `host.docker.internal` | MySQL 端口需以 `0.0.0.0` 发布(1Panel 默认如此),账号 host 为 `%` |
| b **推荐** | compose 追加外部网络,与 MySQL 容器同网 | `<MySQL 容器名>`(如 `1Panel-mysql-xxxx`) | 不暴露额外端口,容器名在 1Panel 容器列表可见 |
| c | 走 docker0 网桥网关 | `172.17.0.1` | 网桥地址随环境可能变化,兜底用 |
路径 b 的 compose 改法(文件末尾已有注释模板,取消注释即生效):
```yaml
networks:
default:
name: 1panel-network
external: true
```
## 3. 配置 .env
```bash
cd deploy
cp .env.example .env
```
填必填项:`DJANGO_SECRET_KEY`(生成命令见文件内注释)、`DJANGO_ALLOWED_HOSTS`(实际域名)、`DB_*`。
**fail-fast 设计**:`DJANGO_ENV=prod` 时缺 `SECRET_KEY` / `ALLOWED_HOSTS` 启动即崩(`RuntimeError`),不带病上线——这是有意为之的护栏,不是 bug。漏配时看容器日志 `docker compose logs web` 即可定位。
## 4. 部署
```bash
docker compose up -d --build
# 建管理员账号(JWT 登录用)
docker compose exec web python manage.py createsuperuser
```
浏览器访问 `http://<服务器IP>:8018/`(配域名后走第 5 步的 HTTPS 网站访问)。
## 5. 域名与 HTTPS(1Panel 建一个网站即可,前后端共用)
**只需要建 1 个站点**:前端(管理后台)、后端 API、SDK 文件共用同一域名(compose 的 nginx 已合并三者)。
步骤:1Panel「网站」→ 创建网站 → **反向代理** → 代理地址填 `127.0.0.1:8018`(**不带 http:// 前缀**,compose 映射端口,见 docker-compose.yml)→ 在该网站设置里申请 Let's Encrypt 证书并开启 HTTPS。
- 前端访问:`https://track.你的域名.com/`
- API:`https://track.你的域名.com/api/...`(同域自动生效)
- SDK:`https://track.你的域名.com/sdk/v1.js`
> 为什么 compose 不直接占 80/443:1Panel 的 OpenResty 已占用宿主 80/443,直接映射会端口冲突。TLS 由 1Panel 网站终结,转发到 compose 的 8018。
## 6. 建站点拿 site_id
登录后台 → 站点管理 → 新建站点(填域名) → 列表里复制 `site_id`(形如 `site_xxxxxxxx`),接入目标网站时用它。
## 7. 目标网站接入
目标站 `<head>` 里加两行(endpoint 与 SDK 地址换成正式域名):
```html
<script>window.ctk = window.ctk || function(){(ctk.q=ctk.q||[]).push(arguments)};
ctk("init", { siteId: "<上一步的 site_id>", endpoint: "https://track.example.com/api/collect/batch" });</script>
<script async src="https://track.example.com/sdk/v1.js"></script>
```
## 8. 定时任务(不做则趋势图历史全零)
1Panel「计划任务」→ 每日 00:10 执行(Shell 脚本):
```bash
docker exec tracker-web python manage.py refresh_stats --days 2
```
`refresh_stats` 聚合昨日明细为每日统计快照(`--days 2` 幂等重算近两天,补齐漏跑)。
## 9. JWT 应急
token 泄露时**唯一**吊销手段是更换 `DJANGO_SECRET_KEY`(JWT 由它签名,换钥即全体登出):重新生成 → 改 `.env` → `docker compose up -d`。后台没有"注销某 token"的接口,这是无状态 JWT 的设计取舍。
## 10. CDN / WAF 注意
目标网站套 CDN/WAF 后,到达采集 API 的 `X-Forwarded-For` 层数会变化(CDN 一层 + 本站 nginx 一层 = 2 层起)。取真实客户端 IP 依赖 DRF `NUM_PROXIES`(当前为 1,对应"仅前置一层可信代理"取末段)。CDN 层数变化后需同步调整 `server/config/settings.py` 的 `NUM_PROXIES` 并重建镜像,否则取到的是 CDN 节点 IP,地域与去重统计失真。
## 11. 大陆网络备用源
| 资源 | 主源 | 备用源 |
|---|---|---|
| admin 模板(Vite 等 npm 依赖) | npm registry | `pnpm config set registry https://registry.npmmirror.com` |
| ip2region xdb | GitHub lionsoul2014/ip2region | gitee.com/lionsoul/ip2region |
| pip 依赖 | pypi.org | 清华源(**Dockerfile 已内置** `-i https://pypi.tuna.tsinghua.edu.cn/simple`) |
---
### 附:常用运维命令
```bash
docker compose logs -f web # 看后端日志
docker compose up -d --build # 改代码后重建
docker compose exec web python manage.py createsuperuser # 再建账号
```