Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ jobs:

image_path = pathlib.Path('.github/workflows/image.yml')
image_path.write_text(image_path.read_text().replace(f'WEATHER_BRIEFING_VERSION: \"{prev}\"', f'WEATHER_BRIEFING_VERSION: \"{version}\"'))

readme_path = pathlib.Path('README.md')
readme_version = f'WEATHER_BRIEFING_VERSION=\"{prev}\"'
readme_content = readme_path.read_text()
if readme_version not in readme_content:
raise RuntimeError(f'README.md does not contain {readme_version}')
readme_path.write_text(
readme_content.replace(readme_version, f'WEATHER_BRIEFING_VERSION=\"{version}\"', 1)
)
"

uv lock
Expand All @@ -61,7 +70,7 @@ jobs:
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git remote set-url origin "https://x-access-token:${RELEASE_GH_PAT}@github.com/${GITHUB_REPOSITORY}.git"

git add pyproject.toml weather_briefing/__init__.py .github/workflows/image.yml uv.lock
git add pyproject.toml weather_briefing/__init__.py .github/workflows/image.yml README.md uv.lock
if git diff --cached --quiet; then
echo "No changes to commit"
else
Expand Down
43 changes: 32 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,40 @@ BRIEFING_STATE_PATH=state/replay.sqlite3 weather-briefing run forecast --at 2026

`run forecast --date YYYY-MM-DD` 可查看当地今天或指定未来日期(例如后天)的 forecast,也可以与 `--run-now` 组合。目标日期只影响要查询和总结的预报日期,实际运行时间、状态写入时间和历史窗口仍使用当前时间。`--at` 只在测试历史回放时覆盖实际运行时间。

```bash
cp env.example .env
cp locations.example.json locations.json
docker buildx build --load -t weather-briefing .
docker volume create weather-briefing-state
docker run -d --name weather-briefing --restart unless-stopped \
--env-file .env \
--mount type=bind,src="$PWD/locations.json",dst=/app/locations.json,readonly \
--mount source=weather-briefing-state,target=/app/state \
weather-briefing
### 使用发布镜像部署

下面的脚本从 Docker Hub 拉取固定版本的多架构镜像,并以非特权用户运行常驻调度器。运行前先在 `ROOT_DIR` 下准备根据 `env.example` 填写的 `.env` 和有效的 `locations.json`;路径和镜像名称可按实际环境调整。

```sh
#!/bin/sh
set -eu

CONTAINER_NAME="weather-briefing"
WEATHER_BRIEFING_IMAGE="icecodexi/${CONTAINER_NAME}"
WEATHER_BRIEFING_VERSION="1.0.0"
ROOT_DIR="${HOME}/${CONTAINER_NAME}"
CONTAINER_ROOT_DIR="/home/nonroot/app"

mkdir -p "${ROOT_DIR}/app/state"
touch "${ROOT_DIR}/.env" "${ROOT_DIR}/locations.json"
test -s "${ROOT_DIR}/rss-sources.json" || printf '[]\n' >"${ROOT_DIR}/rss-sources.json"
chmod 600 "${ROOT_DIR}/.env" "${ROOT_DIR}/locations.json" "${ROOT_DIR}/rss-sources.json"
chown -R 65532:65532 "${ROOT_DIR}"

docker pull "${WEATHER_BRIEFING_IMAGE}:${WEATHER_BRIEFING_VERSION}"
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true
docker run -d \
--name "${CONTAINER_NAME}" \
--restart unless-stopped \
--env-file "${ROOT_DIR}/.env" \
--mount "type=bind,src=${ROOT_DIR}/locations.json,dst=${CONTAINER_ROOT_DIR}/locations.json,readonly" \
--mount "type=bind,src=${ROOT_DIR}/rss-sources.json,dst=${CONTAINER_ROOT_DIR}/rss-sources.json,readonly" \
--mount "type=bind,src=${ROOT_DIR}/app/state,dst=${CONTAINER_ROOT_DIR}/state" \
"${WEATHER_BRIEFING_IMAGE}:${WEATHER_BRIEFING_VERSION}" \
daemon
```

若启用 RSS,再把私密 `rss-sources.json` 以只读方式挂载到容器内配置的同名路径。配置文件不会进入镜像构建上下文
脚本需要有权执行 `chown` 和管理 Docker。RSS 未配置时使用空数组;配置文件以只读方式挂载,SQLite 状态保留在宿主机。升级时修改 `WEATHER_BRIEFING_VERSION` 并重新运行即可,重建容器期间会有短暂停机

也可在持久主机上使用 cron:

Expand Down