Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7.2 KiB
7.2 KiB
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(证书)。
五、日常运维速查
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 重建容器
六、本项目部署接入步骤
域名:jump.hn12301.net(已于 2026-08-02 上线,第一期打卡系统)。
- 在
/opt/services/superjump/建docker-compose.yml:
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(`jump.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
-
docker compose up -d→ 几十秒后https://jump.hn12301.net自动可用(证书自动签发),不用动 Traefik 任何配置。 -
需要数据库时建专用账号(勿用 root):
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:465SSL,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与数据卷定期打包)
十、踩坑记录(务必先看)
- Docker 29 + Traefik v3.5 不兼容:Docker 29 最低 API 1.44,须用 Traefik ≥ v3.6。
- docker exec 喂 SQL 必须加
-i:否则 heredoc 内容不进容器且不报错。 - compose .env 里的
$要写成$$:htpasswd 的$apr1$哈希不转义会被当变量,Basic Auth 永远 401。 - Let's Encrypt 失败重试:Traefik 启动即尝试签发,DNS 未生效会失败;DNS 好后重启 Traefik 容器重新触发。
- Docker Hub 国内直连不通:daemon.json 已配镜像源(docker.m.daocloud.io 等)。
- Gitea 禁止 root:容器内执行 Gitea CLI 必须
-u git。 - 本机代理 fake-ip 污染探测:开发机 Clash 类代理会把域名解析成 198.18.x.x,导致
nc -z显示所有端口 OPEN 的假象。判断真实暴露面必须从服务器侧自探公网 IP,不要信本机探测。 - 远程 heredoc 里的反引号会被 shell 执行:JS 模板字符串经 ssh 传输时反引号变命令替换;用 quoted heredoc('EOF')或先本地写文件再传。
- Kuma SQLite 是 WAL 模式:拷库离线查询要同时拷
kuma.db+kuma.db-wal+kuma.db-shm。 - sshd_config.d 优先级高于主配置:改 SSH 设置时主配置与
50-cloud-init.conf两处都要查。 - Kuma 1.x socket.io API:
addNotification第二参数是 notificationID(新建传null);mysql 监控用database_connection_string(无 password 字段);详见手册第九节第 8 条。
手册验收记录:2026-08-02 全部完成 —— 6 容器全绿;三域名证书生效;Kuma 5 监控项全 UP;SSH 密码登录已关闭;全部凭据已轮换。