- 家长手机号登录 + 孩子设备一次性激活(长期会话) - 周模板自动生成每日任务快照,支持拍照凭证直传对象存储 - 连击计算(空白日自动达成)、家长补卡带标记 - 家长端三标签:今日概览 / 任务模板 / 设备管理 - Docker 独立输出,经 Traefik 接入 jump.hn12301.net Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
145 lines
7.2 KiB
Markdown
145 lines
7.2 KiB
Markdown
# SuperJump 项目指南
|
|
|
|
> 本项目部署在「AI 实验场」服务器(47.98.16.70)。以下为该服务器的部署/运维上下文,
|
|
> 同步自部署手册:`~/Documents/obsidian/工作资料/47.98.16.70(Ai实验场)部署手册_2026-08-02.md`
|
|
> (手册内含全部凭据明文;本文件会进 git,故只记位置不记密码。)
|
|
|
|
## 一、目标服务器
|
|
|
|
- 阿里云 ECS:4 核 15G / Ubuntu 26.04 LTS / 99G 系统盘 / 公网 IP `47.98.16.70`
|
|
- 登录:`ssh aifield`(root,**仅密钥登录**,无密码)
|
|
- 私钥:本机 `~/.ssh/aifield_47.98.16.70_ed25519`,NAS 有备份
|
|
- ⚠️ 私钥丢失 = 失去服务器(只能走阿里云控制台 VNC)
|
|
- 代码托管:本项目 `https://git.hn12301.net/xuchao/SuperJump.git`(自建 Gitea,账号 `xuchao`)
|
|
|
|
## 二、架构
|
|
|
|
- 纯 Docker Compose 手工管理 + Traefik 自动反代 + Let's Encrypt 自动签发/续期证书
|
|
- 流量:`:80` 强制 301 → `:443`(Traefik)→ 各容器
|
|
- 已有域名:`git.hn12301.net`(Gitea)、`status.hn12301.net`(Uptime Kuma)、`traefik.hn12301.net`(Dashboard, Basic Auth);新项目用 `<项目>.hn12301.net`
|
|
- 两个内部网络:
|
|
- `proxy` — Traefik 与所有对外服务
|
|
- `data` — MySQL / Redis / Kuma(需连数据库的服务加入此网络)
|
|
- MySQL / Redis 宿主机**零端口暴露**,仅 data 内网可达(容器内用 `mysql:3306`、`redis:6379` 访问)
|
|
|
|
## 三、凭据获取(不进本文件)
|
|
|
|
| 服务 | 账号 | 密码在哪 |
|
|
| --- | --- | --- |
|
|
| Gitea | `xuchao` | 服务器 `/opt/services/gitea/.env`,或 Obsidian 手册 |
|
|
| MySQL | `root` | 服务器 `/opt/services/mysql/.env` |
|
|
| Redis | — | 服务器 `/opt/services/redis/.env` |
|
|
| Uptime Kuma | `admin` | 服务器 `/opt/services/uptime-kuma/`,或 Obsidian 手册 |
|
|
| Traefik Dashboard | `admin` | 服务器 `/opt/services/traefik/.env` |
|
|
|
|
- 服务器上各服务密码的权威来源:`/opt/services/*/.env`(权限 600)
|
|
- 完整凭据表与哈希备份:Obsidian 部署手册(路径见文首)
|
|
|
|
## 四、服务器目录结构
|
|
|
|
```
|
|
/opt/services/
|
|
├── traefik/ # 反向代理
|
|
├── gitea/ # Git 服务
|
|
├── gitea-runner/ # CI runner(默认基础镜像 node:24-slim)
|
|
├── mysql/ # 数据库
|
|
├── redis/ # 缓存
|
|
└── uptime-kuma/ # 监控(proxy + data 双网络)
|
|
```
|
|
|
|
数据卷:`mysql_mysql_data`、`redis_redis_data`、`gitea_gitea_data`、`kuma_data`、`runner_data`、`traefik_certs`(证书)。
|
|
|
|
## 五、日常运维速查
|
|
|
|
```bash
|
|
ssh aifield # 登录服务器
|
|
|
|
cd /opt/services/<服务> && docker compose ps / restart / logs -f --tail 50
|
|
docker ps # 全部容器
|
|
|
|
# MySQL / Redis 客户端(密码从 .env 现取,不要硬编码)
|
|
docker exec -it mysql mysql -uroot -p"$(grep MYSQL_ROOT_PASSWORD /opt/services/mysql/.env | cut -d= -f2)"
|
|
docker exec -it redis redis-cli -a "$(grep REDIS_PASSWORD /opt/services/redis/.env | cut -d= -f2)"
|
|
|
|
# 改某服务密码:更新对应 .env → docker compose up -d 重建容器
|
|
```
|
|
|
|
## 六、本项目部署接入步骤
|
|
|
|
域名:`superjump.hn12301.net`(或自定;若已有泛解析 `*` → `47.98.16.70` 则免加 DNS A 记录)。
|
|
|
|
1. 在 `/opt/services/superjump/` 建 `docker-compose.yml`:
|
|
|
|
```yaml
|
|
services:
|
|
superjump:
|
|
image: 你的镜像:tag
|
|
container_name: superjump
|
|
restart: unless-stopped
|
|
networks: [proxy, data] # data 仅在需要连 MySQL/Redis 时加
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.docker.network=proxy
|
|
- traefik.http.routers.superjump.rule=Host(`superjump.hn12301.net`)
|
|
- traefik.http.routers.superjump.entrypoints=websecure
|
|
- traefik.http.routers.superjump.tls.certresolver=le
|
|
- traefik.http.services.superjump.loadbalancer.server.port=8080 # 改成容器内实际端口
|
|
networks:
|
|
proxy:
|
|
name: proxy
|
|
external: true
|
|
data:
|
|
name: data
|
|
external: true
|
|
```
|
|
|
|
2. `docker compose up -d` → 几十秒后 `https://superjump.hn12301.net` 自动可用(证书自动签发),**不用动 Traefik 任何配置**。
|
|
|
|
3. 需要数据库时建**专用账号**(勿用 root):
|
|
|
|
```sql
|
|
CREATE DATABASE superjump CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
CREATE USER 'superjump'@'%' IDENTIFIED BY '另起强密码';
|
|
GRANT ALL ON superjump.* TO 'superjump'@'%';
|
|
```
|
|
|
|
语言镜像映射:Java → JRE 镜像;.NET → `mcr.microsoft.com/dotnet/aspnet:9.0`;Python → uvicorn/gunicorn 镜像。需要构建的走 Gitea Actions。
|
|
|
|
## 七、CI(Gitea Actions)
|
|
|
|
- Runner 已注册,标签 `ubuntu-latest` / `ubuntu-24.04` / `ubuntu-22.04`,均映射轻量镜像 `node:24-slim`(含 bash/git/node)
|
|
- workflow 放仓库 `.gitea/workflows/*.yaml`,语法同 GitHub Actions
|
|
- 重型任务在 workflow 里用 `container:` 指定专用镜像,**不要改 runner 默认**(国内拉 docker.gitea.com 基础镜像极慢)
|
|
|
|
## 八、监控(Uptime Kuma)
|
|
|
|
- 5 个监控项(60s 间隔):Gitea(HTTP 2xx)、Traefik-Dashboard(HTTP 401 即存活)、MySQL(连接串探针)、Redis-TCP(端口探针,Kuma 1.x 的 redis 类型不支持密码)、Traefik-443-TCP
|
|
- 告警:QQ 邮箱 SMTP(`smtp.qq.com:465` SSL,`25260062@qq.com`),DOWN/恢复各发一封
|
|
- 改邮箱授权码:Kuma 网页 → Settings → Notifications → 编辑「邮件告警」
|
|
|
|
## 九、安全现状(2026-08-02 已加固验证)
|
|
|
|
- SSH 仅密钥登录(`PasswordAuthentication no` 在**主配置 + sshd_config.d/50-cloud-init.conf 两处**都改了)
|
|
- 阿里云安全组 + UFW:公网仅 22/80/443;fail2ban 运行中
|
|
- MySQL/Redis 架构级零暴露
|
|
- **换机/重装后必做**:阿里云重装会重置 sshd 配置,需重装公钥并再次执行两处 `PasswordAuthentication no`
|
|
- 备份:暂未设置(建议日后:阿里云自动快照 + `/opt/services` 与数据卷定期打包)
|
|
|
|
## 十、踩坑记录(务必先看)
|
|
|
|
1. **Docker 29 + Traefik v3.5 不兼容**:Docker 29 最低 API 1.44,须用 Traefik ≥ v3.6。
|
|
2. **docker exec 喂 SQL 必须加 `-i`**:否则 heredoc 内容不进容器且不报错。
|
|
3. **compose .env 里的 `$` 要写成 `$$`**:htpasswd 的 `$apr1$` 哈希不转义会被当变量,Basic Auth 永远 401。
|
|
4. **Let's Encrypt 失败重试**:Traefik 启动即尝试签发,DNS 未生效会失败;DNS 好后重启 Traefik 容器重新触发。
|
|
5. **Docker Hub 国内直连不通**:daemon.json 已配镜像源(docker.m.daocloud.io 等)。
|
|
6. **Gitea 禁止 root**:容器内执行 Gitea CLI 必须 `-u git`。
|
|
7. **本机代理 fake-ip 污染探测**:开发机 Clash 类代理会把域名解析成 198.18.x.x,导致 `nc -z` 显示所有端口 OPEN 的假象。判断真实暴露面必须**从服务器侧自探公网 IP**,不要信本机探测。
|
|
8. **远程 heredoc 里的反引号会被 shell 执行**:JS 模板字符串经 ssh 传输时反引号变命令替换;用 quoted heredoc('EOF')或先本地写文件再传。
|
|
9. **Kuma SQLite 是 WAL 模式**:拷库离线查询要同时拷 `kuma.db` + `kuma.db-wal` + `kuma.db-shm`。
|
|
10. **sshd_config.d 优先级高于主配置**:改 SSH 设置时主配置与 `50-cloud-init.conf` 两处都要查。
|
|
11. **Kuma 1.x socket.io API**:`addNotification` 第二参数是 notificationID(新建传 `null`);mysql 监控用 `database_connection_string`(无 password 字段);详见手册第九节第 8 条。
|
|
|
|
---
|
|
|
|
*手册验收记录:2026-08-02 全部完成 —— 6 容器全绿;三域名证书生效;Kuma 5 监控项全 UP;SSH 密码登录已关闭;全部凭据已轮换。*
|