Files
2026-09-21 17:30:02 +08:00

15 KiB
Raw Permalink Blame History

腾讯云双应用部署

当前状态与上线前提

目前公网域名 zhouxing199901.site 仍由腾讯云 EdgeOne Pages/Makers 托管游戏。 2026-09-18 已创建广州地域的轻量应用服务器,公网 IP 为 203.195.219.128,配置为 2 核 2GB、40GB 系统盘、Ubuntu 24.04 Docker 镜像。 已登录确认 Docker 29.6.1、Compose 5.3.1 可用。应用现已部署到服务器 /home/ubuntu/wolin。2026-09-19 已开放公网 IP HTTPS 入口 https://203.195.219.128/,尚未切换公网域名。 服务器上的 MySQL 使用独立数据卷,已导入 2026-09-18 20:12(北京时间)的本地快照,共 8 张表、46 条记录,逐表行数与 SHA256 校验通过。 2026-09-18 21:13(北京时间)已验证双入口首页、原游戏文件哈希、登录、六模块只读查询、退出与未登录拦截;报告保存在服务器 artifacts/server-verification.json。 三个容器已启动,数据库与后端健康检查正常。实测空闲时 MySQL 约 473MiB、后端约 63MiB、网关约 10MiB,系统可用内存约 904MiB;此数据不等于并发压力测试结果。 经用户明确同意,备案资源查询服务角色授权已生效。用户随后于 2026-09-18 22:17(北京时间)手动提交首次备案;最新截图显示处于“腾讯云审核”阶段,尚未备案通过。 广州服务器绑定域名对外上线前,需要完成 ICP 备案;当前使用 IP HTTPS 入口,不切换现有域名解析。 本次不修改原 EdgeOne 项目和域名解析,待新服务器验证完成后才切换。

目标布局:

地址 内容 访问控制
/ 双入口首页 公开
/blackjack/ 决战21点,保留当前线上构建 公开
/wolin/ 沃林学生管理系统 管理口令
/wolin/docs 学生系统 API 文档 同一管理口令

云服务器上 Docker Compose 运行 gateway(Caddy HTTPS 入口)、web(FastAPI)、db(MySQL 8.4)。 MySQL 主机名为 db,数据写入 mysql_data 命名卷,不再连接 Windows。 只有入口容器映射 80/443,MySQL 3306 和应用 8004 不开放到公网。 本地原配置 compose.yaml 保留;云端使用独立 compose.cloud.yaml,不要将两者合并启动。

建议小规模使用从腾讯云轻量应用服务器 2 核 4GB、Ubuntu 24.04 LTS 开始,硬盘留足备份空间。 按实际购买页核对地域、带宽、流量、首购和续费价;本次没有代购或产生云资源费用。 中国内地地域的网站开通需满足备案要求,选地域前确认域名备案状态。 参考:轻量应用服务器、使用限制。

保留游戏

deploy/site/blackjack/index.html 原样复制当前线上构建首页,根路径 /_next/static/ 保留所有原资源。 已核对线上首页、原本地构建和迁移副本 SHA256 相同: fbfaa144502f611b00ec9cfe4a08ab495e33a9088aaa3e9f21e4e21da9d56d0d。 原游戏代码与业务规则没有修改。保留 HTTPS 域名后,浏览器 localStorage 的来源范围不因路径改变。 原游戏已有“刷新后累计局数/收益归零”的问题,本次原样保留构建,没有把它作为迁移故障修改。

配置和口令

部署档案 artifacts/wolin-cloud-deployment.tar.gz 不含数据库数据、.env、管理密码或 AI 密钥。 在安装 Docker Engine 和 Compose 插件的服务器上,解包到如 /opt/wolin,然后执行:

cd /opt/wolin
docker pull caddy:2-alpine
python3 scripts/prepare_cloud_env.py
chmod 600 .env.cloud artifacts/cloud-access.txt

脚本创建 .env.cloud(两组独立随机数据库口令、管理密码 scrypt 哈希和会话签名密钥等)及 artifacts/cloud-access.txt(管理员登录口令)。现有文件不覆盖,避免错误轮换数据库密码。 应安全保存登录口令;不把这两个文件提交代码仓库或放入静态目录。

AI 云端配置默认为空。用户选择在服务器自行配置专用密钥,不复用本机密钥。在服务器执行:

python3 /home/ubuntu/wolin/scripts/configure_cloud_ai.py

按提示粘贴专用 DeepSeek API 密钥并回车,输入内容不会回显。工具仅更新 .env.cloud 的 DEEPSEEK_API_KEY,保留数据库和登录配置,以原子替换方式保存为 600 权限文件。 密钥保存后,需要执行 sudo docker compose --env-file .env.cloud -f compose.cloud.yaml up -d --no-deps --wait web 重新创建后端容器,再验证真实 AI 查询。 DEEPSEEK_MODEL 目前为 deepseek-flash,如账户支持的模型不同,修改服务器 .env.cloud 中对应值。 截至 2026-09-19 本次排查,云端仍未配置密钥,等待用户输入;误导性的 PyCharm 专用提示已修正并部署。 当前本地 AI 配置不会自动上传、也不会写入镜像。页面和业务管理不依赖 AI 密钥。 云端配置强制使用新生成的随机数据库口令;原 database.py 的本机默认连接设置只用于兼容原开发方式。 管理入口使用普通网页登录,成功后使用 HttpOnly、SameSite=Strict 的签名会话 Cookie,8 小时后过期。 生产环境 Cookie 设置 Secure,仅通过 HTTPS 传输;本机 HTTP 预演使用 AUTH_COOKIE_SECURE=false。 认证覆盖学生页面、静态资源、所有业务/AI API 和文档;不依赖浏览器原生 HTTP BasicAuth 弹窗。 工作台右上角可退出登录。数据库健康检查仅返回服务状态,不返回业务信息。 这是一组共享管理员凭据,不等于完整的多用户角色权限系统。

数据迁移:本地库 → 服务器库

正式切换前停止业务录入,在本地重新导出一次,避免预演之后的数据遗漏:

Set-Location 'D:\python编程\student_management_system'
python scripts/export_database.py

输出位于忽略的 artifacts/migration/:SQL 文件及校验清单 JSON。 SQL 包含真实业务数据,单独通过 SSH/SCP 上传到服务器的非公开目录,例如 /opt/wolin/artifacts/migration/。 不要将迁移文件放进 deploy/site,不要上传到公开仓库或 EdgeOne 静态站点。 这个过程只读原库,不删除或修改 Windows MySQL。

服务器上先启动空 MySQL,再导入:

cd /opt/wolin
docker compose --env-file .env.cloud -f compose.cloud.yaml up -d --wait db
python3 scripts/restore_cloud_database.py artifacts/migration/实际导出文件.sql --env-file .env.cloud
docker compose --env-file .env.cloud -f compose.cloud.yaml up -d --build --wait

导入工具先检查 SHA256 和目标空库,已有任何表则拒绝导入;成功后核对每张表的行数。 不要使用 main.py 初始化生产库,不要运行 drop_tables 或种子数据替代真实迁移。 云端上线后所有新增、修改、删除只写云端 MySQL,不会自动与本地双向同步。

验证完成后再切换域名

域名切换前的服务器内部验证

生成 .env.cloud 后、首次启动前,将以下配置设为:

SITE_ADDRESS=http://localhost
HTTP_BIND=127.0.0.1
HTTP_PORT=18080
HTTPS_PORT=18443
AUTH_COOKIE_SECURE=false

保留 COMPOSE_PROJECT_NAME=wolin-cloud 和生成的所有口令,再按前文启动数据库、导入快照并启动应用。 此时入口仅监听服务器回环地址,公网不开放学生数据或管理口令;不能直接通过公网 IP 浏览。 需要在本机浏览器查看时,使用自己的 SSH 登录方式建立加密隧道:

ssh -N -L 127.0.0.1:18081:127.0.0.1:18080 ubuntu@203.195.219.128

随后访问 http://localhost:18081/;本机 18081 避开原来使用 18080 的 Docker 预演。 隧道运行期间保留终端。也可以先在服务器内部通过 HTTP 检查健康状态、登录和业务查询。 这是迁移快照预演;正式切换前仍需按前文停止业务录入并迁移最新数据,不能把旧快照当作最终数据。

公网 IP 的 HTTPS 入口(已启用)

用户已授权开放公网 IP 访问。2026-09-19 在服务器启用了 deploy/Caddyfile.ip,使用 Caddy 2.11.4 自动申请和续期可信 IP 证书。腾讯云防火墙保留原有 TCP 80 规则,新增 TCP 443 规则;未公开数据库或后端端口。 外部实际请求确认 HTTPS 返回 200,证书校验成功;HTTP 返回 308 并跳转到 HTTPS。浏览器已验证首页、游戏页面和学生登录页面。 2026-09-19 10:14(北京时间)HTTPS 登录、Secure/HttpOnly/SameSite Cookie、六模块查询、退出及未认证 401 检查全部通过;报告为服务器 artifacts/ip-https-verification.json。记录数仍为学生 7、班级 2、老师 5、顾问 10、成绩 12、就业 6。 变更前配置备份位于服务器 artifacts/before-ip-20260919T015715Z/,包含私密环境配置,不能放到公开目录。

服务器保留所有数据库口令、会话密钥和 COMPOSE_PROJECT_NAME=wolin-cloud,当前入口配置为:

PUBLIC_IP=203.195.219.128
SITE_ADDRESS=https://203.195.219.128
CADDY_CONFIG_FILE=./deploy/Caddyfile.ip
CORS_ORIGINS=https://203.195.219.128
HTTP_BIND=0.0.0.0
HTTP_PORT=80
HTTPS_PORT=443
AUTH_COOKIE_SECURE=true

IP 配置显式使用 Let's Encrypt 的 shortlived ACME 证书,并设置 default_sni 兼容浏览器直接访问 Docker 网关的 IP。需要 Caddy 2.10.1 或更新版本,保留 caddy_data 卷以自动续期;不要用自签名证书替代公网证书校验。 只对外映射网站入口 80/443,MySQL 和后端仍在容器内部网络。HTTP 自动跳转 HTTPS,登录和业务请求通过 HTTPS 传输。 本次已完成服务器配置校验、可信证书申请与外网访问测试。域名解析和原 EdgeOne 游戏保持原状。 IP 与域名是不同的浏览器来源,游戏在原域名下的 localStorage 数据不会自动出现在 IP 地址下。

参考:Caddy TLS 指令、IP 证书说明。

正式切换

确认备案后,将 .env.cloud 恢复为正式域名、CADDY_CONFIG_FILE=./deploy/Caddyfile、CORS_ORIGINS=https://zhouxing199901.site、HTTP_BIND=0.0.0.0、80/443 端口和 AUTH_COOKIE_SECURE=true。 保持 Compose 项目名和数据库卷不变,应用配置通过重新创建 web、gateway 生效。

  1. 在新服务器确认首页、游戏流程、学生页面与六模块查询均正常,未认证请求返回 401。
  2. 只放行网站入口 80/443;SSH 22 尽量限制自己的来源。无需开放 3306 或 8004。
  3. 保留原 EdgeOne 项目和原 CNAME 记录,保存 DNS 配置用于回退。
  4. 将根域名原来指向 EdgeOne 的 CNAME 切换为新服务器公网 IP 的 A 记录,检查有无冲突的 AAAA 记录。
  5. 域名解析到新服务器且 80/443 可达后,Caddy 自动申请并续期 HTTPS 证书。
  6. 重新验证真实域名的首页、两入口、证书和后台数据后再恢复业务录入。

如切换失败,可恢复原 DNS 记录让游戏继续由 EdgeOne 提供。DNS 传播期间旧、新网站可能同时被访问。 不要在此时删除原 EdgeOne 项目,也不要承诺仅靠 DNS 切换实现绝对零停机。

日常维护与备份

docker compose --env-file .env.cloud -f compose.cloud.yaml ps
docker compose --env-file .env.cloud -f compose.cloud.yaml logs --tail=100 web
docker compose --env-file .env.cloud -f compose.cloud.yaml stop
docker compose --env-file .env.cloud -f compose.cloud.yaml start

容器重新创建后数据卷仍在;不要执行 docker compose down -v,它会删除数据库卷。 数据卷解决容器生命周期内的数据保留,不能替代数据库备份。上线后应定期导出数据库,另存一份到服务器之外。 以下命令从云端导出一致性备份(在 Linux 服务器执行):

mkdir -p artifacts/backups
umask 077
docker compose --env-file .env.cloud -f compose.cloud.yaml exec -T db sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" exec mysqldump -uroot --single-transaction --no-tablespaces --set-gtid-purged=OFF "$MYSQL_DATABASE"' > "artifacts/backups/wolin-$(date +%Y%m%d-%H%M%S).sql"

应检查命令退出码和备份文件,并定期在隔离空库验证恢复。不要把生产备份覆盖导回正在使用的数据库。

本机部署预演

.env.preview 使用独立项目名 wolin-cloud-preview,HTTP 只绑定 127.0.0.1:18080,HTTPS 预留 18443。 预演 MySQL 是独立容器与独立卷,不修改原 MySQL,也不修改现有 localhost:8004 容器。

python scripts/prepare_cloud_env.py --preview
docker compose --env-file .env.preview -f compose.cloud.yaml up -d --wait db
python scripts/restore_cloud_database.py artifacts/migration/实际导出文件.sql --env-file .env.preview
docker compose --env-file .env.preview -f compose.cloud.yaml up -d --build --wait

预演访问 http://localhost:18080/,登录口令保存在本机 artifacts/preview-access.txt。 学生系统登录地址为 http://localhost:18080/wolin/login,账号为 admin。 旧版配置可执行 python scripts/prepare_cloud_env.py --preview --upgrade-auth 升级认证,账号密码和数据库口令保留。 升级代码后先构建并重建 web,再重建 gateway,使新网页登录接替旧 BasicAuth。不要先取消旧入口认证再保留无认证旧 web。 此地址仅用于本机验证,不能当作公网部署地址。

2026-09-18 本机预演结果:8 张表、46 条记录已导入独立 MySQL 8.4,逐表行数与文件 SHA256 校验通过。 前端根路径和 /wolin/ 测试、后端 4 组集成测试、公开入口、游戏构建一致性、私有路由认证、静态资源、API 文档前缀与六模块只读查询均通过。 预演 MySQL 容器重新创建后,数据查询再次通过;原 Windows MySQL 各表行数保持不变。 随后修复应用内浏览器 ERR_INVALID_AUTH_CREDENTIALS:将原生 BasicAuth 弹窗替换为网页登录,保留原账号密码。 17 项认证测试通过;容器实测登录、签名 Cookie、六模块查询、退出登录及退出后 API 拦截均通过。 预演的 AI 云端密钥保持为空,未调用外部 AI。当前云服务器同样未配置 AI 密钥;业务管理可用,云端 AI 助手仍需配置后验证。 云服务器内部部署已完成,使用 wolin-cloud 项目及独立 MySQL 数据卷。网关只映射 127.0.0.1:18080 和 127.0.0.1:18443,数据库和后端无公网端口映射。 DNS 切换、真实域名 HTTPS 和公网浏览器验收仍需完成;ICP备案完成前保持现有 EdgeOne 游戏站点不变。

本次默认 PyPI 下载多次出现截断,改用清华镜像后构建成功;服务器如遇相同网络问题,可在 .env.cloud 添加: PIP_INDEX_URL=https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple。 保持 HTTPS 与包校验,不使用跳过证书或关闭哈希检查的方式。