- STORY_WEB_PASSWORD(默认story) 废弃 → STORY_WEB_USERS=名字1:口令1,名字2:口令2; 未配置/口令<8位/口令或用户名重复 → 启动即退出,杜绝弱默认口令裸奔 - cookie 不再存口令原文:登录发 secrets.token_urlsafe(32) 随机token, 会话存 SQLite sessions 表(30天);登出删token;从 USERS 移除某人=吊销其全部会话 - updated_by 改由服务端按会话身份填写,前端自报 by 不再可信;登录框去掉昵称字段 - 登录失败全局递增节流(最多sleep 5s),口令比较用 secrets.compare_digest - Dockerfile/compose 移除一切口令默认值;compose 未设 STORY_WEB_USERS 直接报错 - 顺手修 playtest.js 走位/动画/out_ref 行未转义的存储型XSS(esc补齐)
35 lines
1.5 KiB
Docker
35 lines
1.5 KiB
Docker
# Story 事件协作 Web 编辑器(M6 部署)。
|
||
# 构建上下文 = tools/event_authoring (需含 ir_core / ir_dictionary.json / web)。
|
||
# docker build -f web/Dockerfile -t story-event-web .
|
||
# 或用 web/docker-compose.yml 一键起。
|
||
FROM python:3.12-slim
|
||
|
||
WORKDIR /app
|
||
|
||
# 仅装后端运行依赖(编译器是纯 Python 标准库,无需额外包)
|
||
# PIP_INDEX_URL 默认官方源(可移植);国内构建可 --build-arg 指向清华等镜像加速。
|
||
ARG PIP_INDEX_URL=https://pypi.org/simple
|
||
COPY web/requirements.txt ./web/requirements.txt
|
||
RUN pip install --no-cache-dir --index-url ${PIP_INDEX_URL} -r web/requirements.txt
|
||
|
||
# 编译/校验内核 + 外置词典 + 后端 + 前端
|
||
COPY ir_core ./ir_core
|
||
COPY ir_dictionary.json ./ir_dictionary.json
|
||
COPY web ./web
|
||
|
||
# SQLite 持久化目录(挂卷到此);点位集挂载到 /pointsets(只读)。
|
||
# 注意:镜像里不埋任何口令默认值。STORY_WEB_USERS(名字:口令,…)必须运行时注入,
|
||
# 未配置时 app 启动即退出(拒绝弱口令裸奔)。
|
||
ENV STORY_DB_PATH=/data/story_events.db \
|
||
STORY_POINTSETS_DIR=/pointsets
|
||
RUN mkdir -p /data /pointsets
|
||
|
||
EXPOSE 8787
|
||
WORKDIR /app/web
|
||
|
||
# 探测首页(静态,恒 200):/api/* 无凭证会 401 且 urlopen 会抛异常,故改打 / 。
|
||
HEALTHCHECK --interval=30s --timeout=4s --start-period=8s --retries=3 \
|
||
CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8787/',timeout=3).status==200 else 1)"
|
||
|
||
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8787"]
|