Files
nofx/BUGFIX_CONFIG_DB_2025-11-02.md
Theshyx11 df4af06bc7 docs: 添加 config.db Docker 启动失败 bug 修复文档 (#210)
## 问题描述
Docker Compose 首次启动时,config.db 被创建为目录而非文件,
导致 SQLite 数据库初始化失败,容器不断重启。

错误信息: "unable to open database file: is a directory"

## 发现时间
2025-11-02 00:14 (UTC+8)

## 根本原因
docker-compose.yml 中的卷挂载配置:
  - ./config.db:/app/config.db

当本地 config.db 不存在时,Docker 会自动创建同名**目录**。

## 临时解决方案
1. docker-compose down
2. rm -rf config.db
3. touch config.db
4. docker-compose up -d

## 修复时间
2025-11-02 00:22 (UTC+8)

## 新增文件
- BUGFIX_CONFIG_DB_2025-11-02.md: 详细的 bug 修复报告

## 建议改进
- 在 DOCKER_DEPLOY.md 中添加预启动步骤说明
- 考虑在 Dockerfile 中添加自动初始化脚本

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: shy <shy@nofx.local>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-05 18:21:05 +08:00

194 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Bug修复报告config.db 数据库初始化失败
## 问题发现时间
**2025年11月2日 00:14 (UTC+8)**
## 问题描述
### 错误现象
Docker容器 `nofx-trading` 启动后不断重启,后端服务无法正常运行。
### 错误日志
```
2025/11/02 00:14:18 ❌ 初始化数据库失败: 创建表失败: 执行SQL失败 [CREATE TABLE IF NOT EXISTS ai_models (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL DEFAULT 'default',
name TEXT NOT NULL,
provider TEXT NOT NULL,
enabled BOOLEAN DEFAULT 0,
api_key TEXT DEFAULT '',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)]: unable to open database file: is a directory
```
### 根本原因
在Docker Compose首次启动时如果本地没有 `config.db` 文件docker-compose.yml 中的卷挂载配置:
```yaml
volumes:
- ./config.db:/app/config.db
```
会**自动创建一个同名目录**而不是文件这导致SQLite无法正常打开数据库文件。
## 解决方案
### 临时修复步骤(手动)
1. 停止所有Docker容器
```bash
docker-compose down
```
2. 删除错误创建的 `config.db` 目录
```bash
rm -rf config.db
```
3. 创建空的 `config.db` 文件
```bash
touch config.db
```
4. 重新启动容器
```bash
docker-compose up -d
```
### 长期解决方案(建议)
#### 方案1修改 docker-compose.yml推荐
在启动容器前,使用 `entrypoint``command` 确保文件存在:
```yaml
services:
nofx:
# ... 其他配置
entrypoint: ["/bin/sh", "-c"]
command:
- |
if [ ! -f /app/config.db ]; then
touch /app/config.db
fi
./nofx
```
#### 方案2添加初始化脚本
创建 `docker/init-db.sh`
```bash
#!/bin/sh
if [ ! -f /app/config.db ]; then
echo "Creating config.db file..."
touch /app/config.db
fi
exec "$@"
```
修改 Dockerfile
```dockerfile
COPY docker/init-db.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/init-db.sh
ENTRYPOINT ["init-db.sh"]
CMD ["./nofx"]
```
#### 方案3文档说明
`DOCKER_DEPLOY.md` 中添加预启动步骤:
```markdown
## 启动前准备
在首次运行 docker-compose 之前,请执行:
\`\`\`bash
touch config.db
\`\`\`
这将创建空的数据库文件,防止 Docker 自动创建同名目录。
```
## 修复验证
### 修复后的日志
```
2025/11/02 00:22:06 📋 初始化配置数据库: config.db
2025/11/02 00:22:06 ✓ 配置数据库初始化成功
2025/11/02 00:22:06 🌐 API服务器启动在 http://localhost:8080
```
### 容器状态
```bash
$ docker-compose ps
NAME STATUS
nofx-trading Up (healthy)
nofx-frontend Up (healthy)
```
## 影响范围
### 受影响的版本
- dev 分支2025-11-01之后的版本
- 所有使用新数据库架构的版本
### 受影响的用户
- 首次通过 Docker Compose 部署的用户
- 删除过 `config.db` 后重新启动的用户
### 不受影响的场景
- 使用 PM2 直接运行的部署
- 已经成功启动过一次的 Docker 部署config.db 文件已存在)
## 相关文件
- `docker-compose.yml` - 卷挂载配置
- `config/database.go` - 数据库初始化逻辑
- `main.go` - 应用启动入口
## 建议改进
1.**立即**: 在文档中添加预启动步骤说明
2. ⚠️ **短期**: 修改 Dockerfile 添加自动初始化脚本
3. 💡 **长期**: 考虑使用 Docker 命名卷named volume代替绑定挂载
## 测试清单
- [x] Docker Compose 首次启动
- [x] 删除 config.db 后重新启动
- [x] 数据库表自动创建
- [x] API 服务正常响应
- [x] Web 界面可访问
## 提交信息
```
fix: Docker启动时config.db被创建为目录导致数据库初始化失败
问题描述:
- Docker Compose 首次启动时,卷挂载会将不存在的 config.db 创建为目录
- 导致 SQLite 无法打开数据库文件,容器不断重启
- 错误信息:"unable to open database file: is a directory"
解决方案:
- 手动删除 config.db 目录并创建空文件
- 建议在文档中添加预启动步骤说明
发现时间2025-11-02 00:14 (UTC+8)
修复时间2025-11-02 00:22 (UTC+8)
影响范围:所有使用 Docker Compose 首次部署的用户
```
## 备注
此问题是 Docker Compose 的已知行为:当绑定挂载的源文件不存在时,会自动创建同名**目录**。
参考https://docs.docker.com/storage/bind-mounts/#differences-between--v-and---mount-behavior