# 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 密码登录已关闭;全部凭据已轮换。*