403b8516b0
Co-Authored-By: Claude Code <noreply@anthropic.com>
134 lines
5.6 KiB
Markdown
134 lines
5.6 KiB
Markdown
# 部署指南(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 # 再建账号
|
||
```
|