# 小组作品部署说明 这份说明写给组员,也写给替你部署的 AI(Claude Code、WorkBuddy 等)。把本组令牌和这份说明的地址 https://show.lingnan.top/docs 一起交给 AI,说「按这份说明把项目部署上去」即可。 每组一个固定地址 `https://<组号>.show.lingnan.top/`,组号形如 `mf07`、`mde03`。看作品要先输入课程密码(上课时老师公布)。本组令牌以 `show_` 开头,只能部署本组的作品,不要发给别的组,泄露了找老师重置。 ## 一、项目要满足的约定 项目根目录放一个 `deploy.json`,二选一。 纯静态网页(只有 HTML、CSS、JS,没有后端): ```json {"type": "static", "root": "."} ``` `root` 是 `index.html` 所在的目录,前端打包产物在 `dist/` 就写 `"dist"`。 Python 后端: ```json {"type": "python", "start": "python app.py", "port": 8000} ``` `start` 是启动命令,`port` 是程序监听的端口。常见框架的写法: | 框架 | start | |:--|:--| | Flask | `python app.py`,代码里 `app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 8000)))` | | FastAPI | `uvicorn main:app --host 0.0.0.0 --port 8000` | | Streamlit | `streamlit run app.py` | | Gradio | `python app.py`,`launch()` 不用传参数 | Python 后端另外守住这几条: 1. **监听 0.0.0.0,不要监听 127.0.0.1。** 只监听 127.0.0.1 外面连不进来,这是最常见的失败原因。端口从环境变量 `PORT` 读。 2. **依赖写进 `requirements.txt`,只写项目真正用到的包。** 不要用 `pip freeze` 导出整个环境,那会有上百个包,部署会被拒绝。不要写 pywin32 这类只能在 Windows 上用的包。 3. **密钥从环境变量读,不要写进代码,也不要把 `.env` 打包进去。** 压缩包里的 `.env` 会被忽略。密钥用下面的 `/api/secret` 设置,程序里 `os.environ["DEEPSEEK_API_KEY"]` 读取。 4. **路径用相对于项目目录的写法。** 不能出现 `C:\Users\...` 这种 Windows 路径。读写文本文件写明 `encoding="utf-8"`。 5. **要长期保存的数据写到 `/data`。** 路径在环境变量 `DATA_DIR` 里。项目目录本身可写,但每次重新部署都是全新的一份,写在里面的东西会丢。 6. **不要在服务器上跑本地模型。** 向量化、生成都调用 API。 服务器跑的是 Linux 和 Python 3.12,与你本机不同。在本机能跑不等于上去能跑,部署失败时看返回的程序输出,按提示改。 ## 二、打包 压缩包根目录直接是项目文件(`deploy.json` 在最外层),不超过 50MB。虚拟环境(`venv`、`.venv`)、`__pycache__`、`.git`、`node_modules` 会被自动跳过,但最好别打进去,省上传时间。数据文件太大就别放,改成程序启动时从网上取。 Windows PowerShell 下,在项目目录里运行: ```powershell tar -a -c -f ..\project.zip --exclude=.venv --exclude=venv --exclude=__pycache__ --exclude=.git --exclude=.env * ``` ## 三、接口 所有接口在 `https://show.lingnan.top`,请求头带 `Authorization: Bearer <本组令牌>`。Windows 上用 `curl.exe`(不是 PowerShell 的 `curl` 别名)。 **部署**:把 zip 文件内容作为请求体 POST。部署在服务器上排队进行,接口立即返回。 ```powershell curl.exe -X POST -H "Authorization: Bearer <令牌>" -H "Content-Type: application/zip" --data-binary "@..\project.zip" https://show.lingnan.top/api/deploy ``` **看状态**:部署后每隔 5 秒查一次,直到 `deploy.state` 变成 `ok` 或 `failed`。`deploy_log` 是完整的部署记录,失败时里面有程序输出和可能的原因。 ```powershell curl.exe -H "Authorization: Bearer <令牌>" https://show.lingnan.top/api/status ``` **看程序输出**(Python 后端运行时打印的内容,最多 2000 行): ```powershell curl.exe -H "Authorization: Bearer <令牌>" "https://show.lingnan.top/api/logs?lines=200" ``` **设密钥**:值为空字符串即删除。设完程序自动重启。只能写不能读,状态接口只列名字。 ```powershell curl.exe -X POST -H "Authorization: Bearer <令牌>" -H "Content-Type: application/json" -d "{\"name\":\"DEEPSEEK_API_KEY\",\"value\":\"sk-...\"}" https://show.lingnan.top/api/secret ``` **作品信息**(显示在作品列表上,项目名 40 字内,简介 200 字内): ```powershell curl.exe -X POST -H "Authorization: Bearer <令牌>" -H "Content-Type: application/json" -d "{\"title\":\"项目名\",\"summary\":\"一句话简介\"}" https://show.lingnan.top/api/profile ``` **退回上一版**:`POST /api/rollback`。**重启程序**:`POST /api/restart`。 不想用命令行,可以打开 https://show.lingnan.top/upload ,输入令牌,在网页上做上面所有操作。 ## 四、运行时的限制 - 每组 1GB 空间(代码、依赖、数据合计),Python 后端内存 384MB。 - 30 分钟没人访问,Python 后端会休眠,下次打开时自动唤醒,要等几秒。所以不要依赖程序常驻内存里的东西,要保存的写进 `/data`。 - 程序能访问外网(调用 DeepSeek 等),不能访问服务器内部和其他组。 - 部署失败时,如果之前有能用的版本,会自动退回去,线上不会断。服务器保留最近三个版本。 ## 五、常见问题 | 现象 | 原因与改法 | |:--|:--| | 「程序只监听了 127.0.0.1」 | 改成 `0.0.0.0`,见第一节第 1 条 | | `ModuleNotFoundError` | 包没写进 `requirements.txt` | | 依赖安装失败 | 包名拼错;版本号钉得太死,去掉 `==` 后的版本试试;包只能在 Windows 上用 | | `Read-only file system` | 往项目目录和 `/data` 以外的地方写文件,改写到 `/data` | | `UnicodeDecodeError` | 文件不是 UTF-8,或读写时没写 `encoding="utf-8"` | | 页面能开,AI 功能报错 | 密钥没设,或代码没从环境变量读 | | 静态页面样式、图片丢了 | 引用写成了 `C:/...` 这类本机路径,改成相对路径;或者文件名大小写和引用不一致(Linux 区分大小写) |