## [ERR-20260427-004] Docker 单文件 bind mount 在 atomic-rename 编辑后失效

**日期**: 2026-04-27
**类别**: Docker / 反代配置
**严重度**: 中（改完配置文件以为生效了，实际容器还看旧内容）

### 问题描述
Caddy 容器用 `-v /home/chentao/caddy-config/Caddyfile:/etc/caddy/Caddyfile` 单文件 bind mount。改完 host 端 Caddyfile 后 `caddy reload` 报 "config is unchanged"，实际还在反代旧端口。

### 根因
Docker 单文件 bind mount 跟踪的是 **inode**，不是路径。常见编辑器（Edit 工具、vim 默认、`cp`）写文件用 atomic rename 模式：
1. 写新内容到 tmp 文件
2. `rename(tmp, target)` 替换原文件 ← 新 inode

旧 inode 还被容器持有，容器看到的永远是旧内容。

### 验证方法
```bash
# host 和 container 内 inode 不一致就是断了
stat -c '%i' /home/chentao/caddy-config/Caddyfile
docker exec caddy stat -c '%i' /etc/caddy/Caddyfile
```

### 修复
**最快**：`docker restart caddy` —— 重启时容器会按路径重新挂载，拿到新 inode。`docker cp` 不行（被挂载文件 device busy）。

**长期**：mount 整个目录而不是单个文件：
```bash
# 老
-v /host/path/Caddyfile:/etc/caddy/Caddyfile
# 新
-v /host/caddy-config:/etc/caddy
```
目录挂载跟踪路径，atomic rename 不影响。

### 启示
- 任何容器的"配置文件"挂载，**优先挂目录而非单文件**
- 改了配置后的"是否生效"验证：先 `docker exec <ct> cat <path>`，再调用 reload API
- 如果配置在容器里看是旧的，`reload` 当然也是 no-op

---
