Files
nofx/BUGFIX_CONFIG_DB_2025-11-02.md
T
Theshyx11 6d2c64e91b 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 中添加自动初始化脚本
Co-authored-by: shy <shy@nofx.local>
Co-authored-by: tinkle-community <tinklefund@gmail.com>
2025-11-05 18:21:05 +08:00

4.4 KiB
Raw Blame History

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 中的卷挂载配置:

volumes:
  - ./config.db:/app/config.db

自动创建一个同名目录而不是文件!这导致SQLite无法正常打开数据库文件。

解决方案

临时修复步骤(手动)

  1. 停止所有Docker容器
docker-compose down
  1. 删除错误创建的 config.db 目录
rm -rf config.db
  1. 创建空的 config.db 文件
touch config.db
  1. 重新启动容器
docker-compose up -d

长期解决方案(建议)

方案1:修改 docker-compose.yml(推荐)

在启动容器前,使用 entrypointcommand 确保文件存在:

services:
  nofx:
    # ... 其他配置
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        if [ ! -f /app/config.db ]; then
          touch /app/config.db
        fi
        ./nofx

方案2:添加初始化脚本

创建 docker/init-db.sh

#!/bin/sh
if [ ! -f /app/config.db ]; then
    echo "Creating config.db file..."
    touch /app/config.db
fi

exec "$@"

修改 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 中添加预启动步骤:

## 启动前准备

在首次运行 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

容器状态

$ 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)代替绑定挂载

测试清单

  • Docker Compose 首次启动
  • 删除 config.db 后重新启动
  • 数据库表自动创建
  • API 服务正常响应
  • 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