MQTT-FIX-T02: bound Docker logs and document production rollout
This commit is contained in:
1 parent
876754be56
commit
f6ef99e34f
4 files changed
+181
-9
No files matched your search
@@ -590,10 +590,155 @@ docker compose -f docker-compose.yml pull
|
||||
docker compose -f docker-compose.yml up -d
|
||||
```
|
||||
|
||||
### Docker 日志轮转与生产应用
|
||||
|
||||
源码 Compose 为 `app` 和一次性 `migration` 服务配置 Docker `json-file` 日志轮转:单个
|
||||
日志文件最多约 10 MiB,最多保留 3 个文件。开发 override 继承这项设置。Docker 管理这些
|
||||
文件,通常位于宿主机
|
||||
`/var/lib/docker/containers/<完整容器ID>/<完整容器ID>-json.log`;路径取决于 Docker data
|
||||
root,`docker logs` / `docker compose logs` 是查看容器日志的接口。轮转会限制每个容器的
|
||||
日志保留量,较旧内容会被 Docker 轮转淘汰。不要手动删除或编辑 Docker 管理的日志文件。
|
||||
|
||||
`docker restart` 只重启现有容器,不会更新容器创建时保存的 logging 配置;须重建容器。
|
||||
本机开发可重新执行上面的 Compose 命令。生产设备的 Compose 位于
|
||||
`/home/tianyu/.local/share/homeautomation`,与本仓库源码 Compose 分离。部署时只把两个
|
||||
服务的 `logging` 块合并到生产 Compose 对应服务中,并保留生产端已有的 `.env`、设备映射、
|
||||
`group_add`、volume、端口和其他部署设置;不要用完整源码 Compose 覆盖生产文件。
|
||||
|
||||
要同步的配置块如下,分别放在生产文件的 `services.app` 和 `services.migration` 下:
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
```
|
||||
|
||||
生产变更只供人工维护窗口执行,需在生产目录操作。先备份生产 Compose(以及已有的环境文件),
|
||||
并且只把 `app`、`migration` 的 `logging` 块同步到生产文件;不要复制或覆盖整份生产 Compose。
|
||||
保留原有设备映射、`group_add`、volume、端口、环境变量和其他部署设置。编辑后用生产实际使用的
|
||||
Compose 文件组合及合成环境值运行 `docker compose ... config --quiet` 检查;后续所有 Compose 命令都要带上相同生产文件组合和
|
||||
`.mqtt-fix-image-pin.yml`,任何重建命令都带 `--pull never --no-build`;不要把展开后的配置
|
||||
(可能含凭据)打印或贴入报告。以下命令在生产目录执行,示例假设生产基础文件名为
|
||||
`docker-compose.yml`;若实际启动时显式使用其他 `-f` 文件,应在每条命令中原样保留该文件组合。
|
||||
|
||||
先确定本次要走的镜像路径,并创建仅用于固定镜像的持久 override。该文件只设置两个服务的
|
||||
`image`,生产 Compose 仍负责其余设置。只应用日志配置时,不能假设本地 `latest` 标签仍指向
|
||||
正在运行的镜像:先从运行中的 app 容器读取不可变 image ID,将其记录并加上受控本地标签,
|
||||
然后固定这个标签。命令示例:
|
||||
|
||||
```bash
|
||||
cd /home/tianyu/.local/share/homeautomation
|
||||
MQTT_FIX_BACKUP="compose.before-mqtt-fix-$(date +%Y%m%d-%H%M%S).yml"
|
||||
MQTT_FIX_ENV_BACKUP="env.before-mqtt-fix-$(date +%Y%m%d-%H%M%S).bak"
|
||||
MQTT_FIX_RECORD="mqtt-fix-maintenance-record.txt"
|
||||
MQTT_FIX_PIN_BACKUP="image-pin.before-mqtt-fix.yml"
|
||||
MQTT_FIX_APP_ID="$(docker inspect -f '{{.Image}}' home-automation-app)"
|
||||
MQTT_FIX_OLD_REPODIGESTS="$(docker image inspect -f '{{json .RepoDigests}}' "$MQTT_FIX_APP_ID")"
|
||||
printf 'previous app image ID: %s\nprevious app RepoDigests: %s\n' "$MQTT_FIX_APP_ID" "$MQTT_FIX_OLD_REPODIGESTS" | tee -a "$MQTT_FIX_RECORD"
|
||||
MQTT_FIX_APP_IMAGE="home-automation:prod-before-mqtt-fix"
|
||||
docker image tag "$MQTT_FIX_APP_ID" "$MQTT_FIX_APP_IMAGE"
|
||||
printf 'previous app local pin: %s\n' "$MQTT_FIX_APP_IMAGE" | tee -a "$MQTT_FIX_RECORD"
|
||||
cp docker-compose.yml "$MQTT_FIX_BACKUP"
|
||||
if [ -f .env ]; then cp .env "$MQTT_FIX_ENV_BACKUP"; fi
|
||||
if [ -f .mqtt-fix-image-pin.yml ]; then cp .mqtt-fix-image-pin.yml "$MQTT_FIX_PIN_BACKUP"; fi
|
||||
printf 'Compose backup: %s\n.env backup (if present): %s\nprevious image pin backup (if present): %s\n' "$MQTT_FIX_BACKUP" "$MQTT_FIX_ENV_BACKUP" "$MQTT_FIX_PIN_BACKUP" | tee -a "$MQTT_FIX_RECORD"
|
||||
cat > .mqtt-fix-image-pin.yml <<YAML
|
||||
services:
|
||||
app:
|
||||
image: ${MQTT_FIX_APP_IMAGE}
|
||||
migration:
|
||||
image: ${MQTT_FIX_APP_IMAGE}
|
||||
YAML
|
||||
```
|
||||
|
||||
`.mqtt-fix-image-pin.yml` 保存已核验的镜像选择;不要删除它或在后续 Compose 操作中省略它。
|
||||
只有明确部署另一个已核验的镜像时才更新该文件。
|
||||
|
||||
在编辑生产文件的 `logging` 块后,用同一镜像 pin 和合成环境变量静态检查配置,并通过显式
|
||||
override 固定镜像身份。`--env-file /dev/null` 可避免从部署 `.env` 取值;命令行变量只用于
|
||||
Compose 插值。不要输出 `config` 展开结果:
|
||||
|
||||
```bash
|
||||
WARMTELINK_DEVICE_PATH=/dev/synthetic-device WARMTELINK_SERIAL_GID=12345 TZ=Europe/Amsterdam \
|
||||
docker compose --env-file /dev/null -f docker-compose.yml -f .mqtt-fix-image-pin.yml config --quiet
|
||||
```
|
||||
|
||||
若同时部署 MQTT 源码修复,须先确认修复已合入并发布。显式拉取已发布的版本 tag(不要用
|
||||
可变 `latest`),从本地镜像记录 registry digest,并在 override 中用 digest 固定目标;先核验
|
||||
该 tag/digest 对应包含修复的发布,再继续。示例中的 `<published-tag>` 应替换为已核验的版本:
|
||||
|
||||
```bash
|
||||
MQTT_FIX_RELEASE_TAG='code.wanderingbadger.dev/tliu93/home-automation:REPLACE_WITH_VERIFIED_TAG'
|
||||
docker pull "$MQTT_FIX_RELEASE_TAG"
|
||||
MQTT_FIX_NEW_REPODIGESTS="$(docker image inspect -f '{{json .RepoDigests}}' "$MQTT_FIX_RELEASE_TAG")"
|
||||
printf 'target release tag: %s\ntarget RepoDigests: %s\n' "$MQTT_FIX_RELEASE_TAG" "$MQTT_FIX_NEW_REPODIGESTS" | tee -a "$MQTT_FIX_RECORD"
|
||||
MQTT_FIX_APP_IMAGE='code.wanderingbadger.dev/tliu93/home-automation@sha256:REPLACE_WITH_VERIFIED_DIGEST'
|
||||
cat > .mqtt-fix-image-pin.yml <<YAML
|
||||
services:
|
||||
app:
|
||||
image: ${MQTT_FIX_APP_IMAGE}
|
||||
migration:
|
||||
image: ${MQTT_FIX_APP_IMAGE}
|
||||
YAML
|
||||
printf 'selected fixed app image: %s\n' "$MQTT_FIX_APP_IMAGE" | tee -a "$MQTT_FIX_RECORD"
|
||||
```
|
||||
|
||||
将镜像 digest 与发布记录中的目标源码提交对应关系核验后,把确认过的
|
||||
`MQTT_FIX_APP_IMAGE` 用于上述 override 和 `config --quiet` 检查。源码修复尚未发布时,
|
||||
只走前述运行中 image ID 固定路径,不执行 `docker pull`。纯应用代码修复不需要启动 migration;
|
||||
配置更新时可用 `create` 重建 migration 容器但不启动一次性迁移任务。
|
||||
|
||||
容器必须重建才能采用新日志策略。重建 app 会造成短暂采集与 API 中断;安排维护窗口并确认
|
||||
设备采集可恢复。重建前如需留存旧 Docker 日志,可将 `docker logs --timestamps
|
||||
home-automation-app` 输出重定向到受控备份文件,并确认文件可读;此步骤只导出日志,不删除
|
||||
Docker 文件。Docker 可能在移除旧容器时一并移除其 json-file 日志,因此不要假设重建后旧
|
||||
日志仍可从新容器读取。
|
||||
|
||||
确认配置、logging 块和固定镜像后,在生产目录应用容器配置(避免启动 migration)。每条重建
|
||||
命令都显式使用 image pin 并禁止隐式拉取,且保留生产基础 Compose 与原有部署设置:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.yml -f .mqtt-fix-image-pin.yml create --pull never --no-build --force-recreate migration
|
||||
docker compose -f docker-compose.yml -f .mqtt-fix-image-pin.yml up -d --no-deps --pull never --no-build --force-recreate app
|
||||
docker inspect -f '{{.HostConfig.LogConfig.Type}} {{json .HostConfig.LogConfig.Config}}' home-automation-app
|
||||
docker inspect -f '{{.Image}}' home-automation-app
|
||||
docker compose -f docker-compose.yml -f .mqtt-fix-image-pin.yml ps
|
||||
docker compose -f docker-compose.yml -f .mqtt-fix-image-pin.yml logs --tail=100 app
|
||||
```
|
||||
|
||||
检查 `inspect` 结果为 `json-file`、`max-size` 为 `10m`、`max-file` 为 `3`,app 为运行状态,
|
||||
近期日志无启动错误,之后确认 MQTT 与采集恢复。回退时恢复备份的生产 Compose(或恢复旧
|
||||
logging 块)。两种镜像路径都可用维护记录中的旧 app image ID 回退:确认本地旧镜像仍在后,
|
||||
将持久 pin 文件恢复为记录的旧本地 pin(或由记录的 image ID 重新打回该标签),并继续使用该文件:
|
||||
|
||||
```bash
|
||||
docker image inspect home-automation:prod-before-mqtt-fix >/dev/null
|
||||
cat > .mqtt-fix-image-pin.yml <<'YAML'
|
||||
services:
|
||||
app:
|
||||
image: home-automation:prod-before-mqtt-fix
|
||||
migration:
|
||||
image: home-automation:prod-before-mqtt-fix
|
||||
YAML
|
||||
WARMTELINK_DEVICE_PATH=/dev/synthetic-device WARMTELINK_SERIAL_GID=12345 TZ=Europe/Amsterdam \
|
||||
docker compose --env-file /dev/null -f docker-compose.yml -f .mqtt-fix-image-pin.yml config --quiet
|
||||
docker compose -f docker-compose.yml -f .mqtt-fix-image-pin.yml create --pull never --no-build --force-recreate migration
|
||||
docker compose -f docker-compose.yml -f .mqtt-fix-image-pin.yml up -d --no-deps --pull never --no-build --force-recreate app
|
||||
```
|
||||
|
||||
源码更新路径也使用开头记录的旧 app image ID/pin 回退,无需依赖已变化的 `latest`。若本地
|
||||
旧 image ID 已不存在,则用维护记录中保存的旧 RepoDigest 显式拉取旧镜像,核对身份后打回原 pin
|
||||
标签,再按上面的回退步骤操作。记录本次和回退使用的 image ID/digest、固定 pin 文件内容、生产
|
||||
Compose 及 `.env` 备份文件名、logging inspect 结果及验证时间。回退同样会重建容器、造成短暂
|
||||
中断;重建前需另行导出想保留的当前容器日志。保留 `.mqtt-fix-image-pin.yml` 供后续 Compose
|
||||
操作继续使用;不要删除 Docker 日志、备份或其他生产文件。
|
||||
|
||||
持续查看日志:
|
||||
|
||||
```bash
|
||||
docker compose logs -f app
|
||||
docker compose -f docker-compose.yml -f .mqtt-fix-image-pin.yml logs -f app
|
||||
```
|
||||
|
||||
## Container Image CI
|
||||
|
||||
Reference in new issue
Block a user