diff --git a/docs/BAOTA.md b/docs/BAOTA.md index 5d66d76..7650e73 100644 --- a/docs/BAOTA.md +++ b/docs/BAOTA.md @@ -71,11 +71,25 @@ curl -s http://127.0.0.1:3130/api/health # {"ok":true,"service":"zhimingge","apiAi":true,...} ``` -更多 Docker 说明见 [DOCKER.md](./DOCKER.md)。 +更多 Docker 说明见 [DOCKER.md](./DOCKER.md)(含**镜像清理**)。 ---- +### 2.5 清理无用 Docker 镜像 + +多次 `build --no-cache` 后磁盘会堆积旧层,建议定期执行: + +```bash +cd /opt/zhimingge +bash scripts/docker-prune.sh +``` + +深度清理(删除所有未被容器使用的镜像): + +```bash +bash scripts/docker-prune.sh --all +``` + +详细说明见 [DOCKER.md — 镜像清理](./DOCKER.md#镜像清理)。 -## 三、宝塔添加站点与反向代理 ### 3.1 添加网站 diff --git a/docs/DOCKER.md b/docs/DOCKER.md index b4ea184..57552f6 100644 --- a/docs/DOCKER.md +++ b/docs/DOCKER.md @@ -51,13 +51,108 @@ docker compose up -d ```bash docker compose ps # 状态 -docker compose logs -f zhimingge # 日志 +docker compose logs -f zhimingge # 日志 docker compose restart zhimingge # 重启 docker compose down # 停止并删除容器 docker compose up -d --build # 重建并启动 ``` -## 环境变量 +## 镜像清理 + +每次 `docker compose build --no-cache` 会在磁盘上留下**旧层**和 **`` 悬空镜像**,长期不清理会占满磁盘。 + +### 查看占用 + +```bash +docker system df # 汇总:镜像 / 容器 / 构建缓存各占多少 +docker images # 列出所有镜像 +docker images zhimingge # 仅知命阁(通常只有 zhimingge:latest) +``` + +### 推荐:安全清理(不影响正在运行的容器) + +在项目目录执行: + +```bash +cd /opt/zhimingge +bash scripts/docker-prune.sh +``` + +等价手动命令: + +```bash +docker image prune -f # 删除悬空镜像 +docker builder prune -f # 删除构建缓存 +``` + +### 深度清理:删除所有未使用的镜像 + +**不会删除**正在被 `zhimingge` 容器使用的 `zhimingge:latest`,但会删掉其他项目的闲置镜像: + +```bash +bash scripts/docker-prune.sh --all +# 或 +docker image prune -a -f +``` + +### 删除指定镜像 + +```bash +# 先确认没有容器在用(STATE 应为 Up) +docker compose ps + +# 按镜像 ID 删除(把 abc123 换成 docker images 里的 IMAGE ID) +docker rmi abc123 + +# 强制删除(仅当该镜像未被任何容器使用时) +docker rmi -f abc123 +``` + +**不要**在容器仍在运行时执行 `docker rmi zhimingge:latest`,会失败或导致异常。 + +### 停止服务并删除本项目镜像 + +仅当需要完全卸载、或镜像损坏需从零重建时: + +```bash +cd /opt/zhimingge +docker compose down # 停止并删除容器 +docker rmi zhimingge:latest # 删除知命阁镜像 +docker compose build --no-cache +docker compose up -d +``` + +或使用 Compose 自带选项(停止容器并删除**本项目构建的**镜像): + +```bash +docker compose down --rmi local +``` + +### 一键释放最多空间(慎用) + +会删除**所有**未使用的镜像、容器、网络(同一台机器上其他 Docker 项目也会受影响): + +```bash +docker system prune -a -f +``` + +### 建议节奏 + +| 时机 | 操作 | +|------|------| +| 每次 `docker compose build` 之后 | `bash scripts/docker-prune.sh` | +| 磁盘紧张 | `bash scripts/docker-prune.sh --all` | +| 仅本项目重装 | `docker compose down --rmi local` 后重新 build | + +### 排错:清理后服务起不来 + +```bash +cd /opt/zhimingge +docker compose build --no-cache +docker compose up -d --force-recreate +curl -s http://127.0.0.1:3130/api/health +``` + 通过 `.env.local` 注入容器(见 `docker-compose.yml` 的 `env_file`): @@ -103,5 +198,6 @@ docker compose up -d --build | AI 失败 | 检查 `.env.local` 中 `OPENAI_API_KEY`;`docker exec zhimingge printenv OPENAI_API_KEY` | | 页面 AI 空白、curl 本地正常 | Nginx/宝塔未关缓冲或未反代域名,见 [BAOTA.md](./BAOTA.md) | | 卦辞 404 | 确认镜像内 `/app/content/zhouyi/docs` 存在 | +| 磁盘满 / 镜像过多 | `bash scripts/docker-prune.sh`,见 [镜像清理](#镜像清理) | 构建在镜像内完成,**无需**在宿主机单独 `npm install` / `npm run build`。 diff --git a/scripts/docker-deploy.sh b/scripts/docker-deploy.sh index 91bc6b8..649660f 100644 --- a/scripts/docker-deploy.sh +++ b/scripts/docker-deploy.sh @@ -54,3 +54,6 @@ done curl -s -o /dev/null -w "首页 HTTP %{http_code}\n" "http://127.0.0.1:${APP_PORT}/" || true echo "==> 部署完成。日志:docker compose logs -f zhimingge" +echo "" +echo "==> 可选:清理无用镜像释放磁盘" +echo " bash scripts/docker-prune.sh" diff --git a/scripts/docker-prune.sh b/scripts/docker-prune.sh new file mode 100644 index 0000000..d5e2a9f --- /dev/null +++ b/scripts/docker-prune.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# 清理 Docker 无用镜像与构建缓存 +# 用法: +# bash scripts/docker-prune.sh # 安全:悬空镜像 + 构建缓存 +# bash scripts/docker-prune.sh --all # 额外删除未被任何容器使用的镜像 + +set -euo pipefail + +APP_DIR="${APP_DIR:-/opt/zhimingge}" +cd "$APP_DIR" 2>/dev/null || cd "$(dirname "$0")/.." + +echo "==> 当前磁盘占用" +docker system df +echo "" + +echo "==> 当前知命阁相关镜像" +docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}\t{{.CreatedSince}}" \ + | head -1 +docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}\t{{.CreatedSince}}" \ + | grep -E "zhimingge|^REPOSITORY" || true +echo "" + +echo "==> 删除悬空镜像(,多为 rebuild 后遗留)..." +docker image prune -f + +echo "==> 清理构建缓存..." +docker builder prune -f + +if [[ "${1:-}" == "--all" ]]; then + echo "" + echo "==> 删除未被任何容器使用的镜像(不含正在运行的 zhimingge:latest)..." + docker image prune -a -f +fi + +echo "" +echo "==> 清理后磁盘占用" +docker system df +echo "" +echo "完成。若仍占用较大,可查看:docker images -a"