# 知命阁 Docker 部署

> 推荐生产部署方式，端口 **3130**

## 前置条件

```bash
# Ubuntu 安装 Docker
apt update
apt install -y docker.io docker-compose-v2
systemctl enable docker --now
docker --version
docker compose version
```

## 首次部署

```bash
cd /opt
git clone https://git.bz121.com/dekun/zhimingge.git zhimingge
cd /opt/zhimingge

# 环境变量（必填 OPENAI_API_KEY）
cp .env.example .env.local
nano .env.local
chmod 600 .env.local

# 构建并启动
docker compose build
docker compose up -d
```

访问：`http://服务器IP:3130`

## 日常更新

```bash
cd /opt/zhimingge
bash scripts/docker-deploy.sh
```

或手动：

```bash
git pull origin main
docker compose build
docker compose up -d
```

## 常用命令

```bash
docker compose ps                    # 状态
docker compose logs -f zhimingge     # 日志
docker compose restart zhimingge     # 重启
docker compose down                  # 停止并删除容器
docker compose up -d --build         # 重建并启动
```

## 镜像清理

每次 `docker compose build --no-cache` 会在磁盘上留下**旧层**和 **`<none>` 悬空镜像**，长期不清理会占满磁盘。

### 查看占用

```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      # 删除悬空镜像 <none>
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`）：

| 变量 | 必填 | 说明 |
|------|------|------|
| `OPENAI_API_KEY` | 是 | AI 接口密钥 |
| `OPENAI_BASE_URL` | 否 | 默认 `https://op.bz121.com/v1` |
| `OPENAI_MODEL` | 否 | 默认 `huihui_ai/gemma-4-abliterated:e4b` |
| `PORT` | 否 | 容器内 3130 |

## 防火墙

```bash
ufw allow 3130
# 或使用 Nginx / 宝塔 反代 80/443 → 3130（推荐，不必对公网开放 3130）
```

域名与 AI 流式反代完整说明见 [BAOTA.md](./BAOTA.md)。

## PWA 安装

应用已支持添加到主屏幕（手机 / 桌面 Chrome、Edge 等）：

- 首次访问会提示「安装知命阁」
- iOS Safari：分享 → 添加到主屏幕
- 需 HTTPS 访问（经宝塔域名）

## 从 PM2 迁移

```bash
pm2 stop zhimingge
pm2 delete zhimingge
cd /opt/zhimingge
docker compose up -d --build
```

## 排错

| 现象 | 处理 |
|------|------|
| 构建慢 / 超时 | Dockerfile 使用 `.npmrc` 国内镜像；重试 `docker compose build` |
| 容器反复重启 | `docker compose logs zhimingge` 查看报错 |
| 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`。
