fix(web): revalidate app assets and rename compose example
This commit is contained in:
1 parent
eff4b0149d
commit
1b08854b25
6 files changed
+25
-10
No files matched your search
@@ -7,6 +7,10 @@ config.json.tmp
|
|||||||
data/
|
data/
|
||||||
*.journal.jsonl
|
*.journal.jsonl
|
||||||
|
|
||||||
|
# 从示例复制出的本地 compose 文件
|
||||||
|
compose.yml
|
||||||
|
docker-compose.yml
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|||||||
+1
-1
@@ -700,7 +700,7 @@ uv run python tests/test_moves.py
|
|||||||
### P4:可选部署
|
### P4:可选部署
|
||||||
|
|
||||||
- 反向代理、TLS、远程访问鉴权;
|
- 反向代理、TLS、远程访问鉴权;
|
||||||
- 仓库已提供 `Dockerfile` / `docker-compose.yml` / `config.docker.example.json`;容器内执行 `python app.py --config /config/config.json`,挂载 `/config` 与 `/data`;
|
- 仓库已提供 `Dockerfile` / `compose.example.yml` / `config.docker.example.json`;容器内执行 `python app.py --config /config/config.json`,挂载 `/config` 与 `/data`;
|
||||||
- Docker 不作为本机开发、联调或日常运行的前置条件。
|
- Docker 不作为本机开发、联调或日常运行的前置条件。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -209,26 +209,33 @@ uv run python tools/import_fans_history.py --from-file data.js --days 90
|
|||||||
|
|
||||||
## 快速部署(Docker)
|
## 快速部署(Docker)
|
||||||
|
|
||||||
仓库根目录已包含 `Dockerfile`、`docker-compose.yml`、`.dockerignore` 和 `config.docker.example.json`。
|
仓库根目录已包含 `Dockerfile`、`compose.example.yml`、`.dockerignore` 和 `config.docker.example.json`。Compose 文件是示例,需要显式指定:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# 1. 准备服务器配置;至少填写 B 站 Cookie / Telegram,并保留 /data 绝对路径
|
# 1. 准备服务器配置;至少填写 B 站 Cookie / Telegram,并保留 /data 绝对路径
|
||||||
Copy-Item config.docker.example.json config.json
|
Copy-Item config.docker.example.json config.json
|
||||||
|
|
||||||
# 2. 构建并后台启动
|
# 2. 构建并后台启动
|
||||||
docker compose up -d --build
|
docker compose -f compose.example.yml up -d --build
|
||||||
|
|
||||||
# 3. 查看日志与健康状态
|
# 3. 查看日志与健康状态
|
||||||
docker compose logs -f
|
docker compose -f compose.example.yml logs -f
|
||||||
curl http://127.0.0.1:8080/api/health
|
curl http://127.0.0.1:8080/api/health
|
||||||
```
|
```
|
||||||
|
|
||||||
|
如果希望省略 `-f`,可以复制为 `compose.yml`(该文件不提交):
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Copy-Item compose.example.yml compose.yml
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
- 容器执行 `python app.py --config /config/config.json`,同时运行只读 Web、调度和 Telegram;
|
- 容器执行 `python app.py --config /config/config.json`,同时运行只读 Web、调度和 Telegram;
|
||||||
- `config.json` 挂载到 `/config/config.json`,`data/` 挂载到 `/data/`;
|
- `config.json` 挂载到 `/config/config.json`,`data/` 挂载到 `/data/`;
|
||||||
- 服务器配置需使用 `web.host = 0.0.0.0` 并设置 `web.auth_token`,否则服务拒绝启动;
|
- 服务器配置需使用 `web.host = 0.0.0.0` 并设置 `web.auth_token`,否则服务拒绝启动;
|
||||||
- `storage.database_path` 使用 `/data/app.db`,`storage.backup_dir` 使用 `/data/backup`;
|
- `storage.database_path` 使用 `/data/app.db`,`storage.backup_dir` 使用 `/data/backup`;
|
||||||
- 首次部署可先在本地执行 `uv run python app.py auth --account read` 扫码,再把生成好的 `config.json` 放到服务器;
|
- 首次部署可先在本地执行 `uv run python app.py auth --account read` 扫码,再把生成好的 `config.json` 放到服务器;
|
||||||
- 也可在容器内扫码:`docker compose run --rm board python app.py auth --account read --no-browser`,二维码会打印在临时文件路径,可用 `docker cp` 取出;
|
- 也可在容器内扫码:`docker compose -f compose.example.yml run --rm board python app.py auth --account read --no-browser`,二维码会打印在临时文件路径,可用 `docker cp` 取出;
|
||||||
- 数据卷包含数据库、备份与预览库,建议定期备份 `/data`。
|
- 数据卷包含数据库、备份与预览库,建议定期备份 `/data`。
|
||||||
|
|
||||||
不使用 Compose 时:
|
不使用 Compose 时:
|
||||||
|
|||||||
File renamed without changes.
+1
-1
@@ -701,7 +701,7 @@ fan_delta_cum = follower(d) - follower(首日)
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
Dockerfile 单容器镜像(只安装 httpx 0.28.1)
|
Dockerfile 单容器镜像(只安装 httpx 0.28.1)
|
||||||
docker-compose.yml 挂载 ./config.json → /config、./data → /data
|
compose.example.yml 挂载 ./config.json → /config、./data → /data(复制为 compose.yml 后使用)
|
||||||
.dockerignore 排除凭据、数据、测试与本地环境
|
.dockerignore 排除凭据、数据、测试与本地环境
|
||||||
config.docker.example.json 服务器配置样例(0.0.0.0 + /data 绝对路径)
|
config.docker.example.json 服务器配置样例(0.0.0.0 + /data 绝对路径)
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -397,13 +397,17 @@ border-color:#3a2c22;color:#f3e9dc}button{background:#e9b97c;color:#2a1a10}}
|
|||||||
}:
|
}:
|
||||||
content_type += "; charset=utf-8"
|
content_type += "; charset=utf-8"
|
||||||
payload = target.read_bytes()
|
payload = target.read_bytes()
|
||||||
|
vendor_root = (STATIC_ROOT / "vendor").resolve()
|
||||||
|
try:
|
||||||
|
target.relative_to(vendor_root)
|
||||||
|
cache_control = "public, max-age=86400"
|
||||||
|
except ValueError:
|
||||||
|
# 应用自身的 JS/CSS/HTML 每次重新校验,保证升级后浏览器立刻拿到新版。
|
||||||
|
cache_control = "no-cache"
|
||||||
self.send_response(HTTPStatus.OK)
|
self.send_response(HTTPStatus.OK)
|
||||||
self.send_header("Content-Type", content_type)
|
self.send_header("Content-Type", content_type)
|
||||||
self.send_header("Content-Length", str(len(payload)))
|
self.send_header("Content-Length", str(len(payload)))
|
||||||
self.send_header(
|
self.send_header("Cache-Control", cache_control)
|
||||||
"Cache-Control",
|
|
||||||
"no-cache" if target.name == "index.html" else "public, max-age=3600",
|
|
||||||
)
|
|
||||||
self._security_headers()
|
self._security_headers()
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
if method != "HEAD":
|
if method != "HEAD":
|
||||||
|
|||||||
Reference in new issue
Block a user