Docker中SQLite绑定挂载运行正常,使用命名卷报重复列错误
问题原因
该问题和权限配置无关,核心是Docker两种挂载模式的行为差异+镜像构建时意外打包了本地SQLite文件两个因素共同导致的。
两种挂载模式的行为差异
- 绑定挂载(
-v /home/user/data:/app/data):宿主机目录会直接覆盖容器内的/app/data目录,镜像内部/app/data下的所有内容都会被屏蔽不生效。你宿主机目录下的数据库已经完成过全量迁移,isPublic字段已经存在,且umzug迁移记录表中已有对应迁移的执行记录,不会重复执行迁移逻辑,因此运行正常。 - 命名卷挂载(
-v appdata:/app/data):如果挂载的是空的新命名卷,Docker默认会先把容器内目标目录的原有内容复制到命名卷中,再完成挂载。
镜像构建的隐藏问题
你的Dockerfile中执行了COPY . .命令,如果项目根目录的data文件夹没有被加入.dockerignore配置,本地开发环境生成的SQLite数据库文件会被直接打包到镜像内的/app/data目录下。这个镜像内置的数据库已经存在isPublic字段,但要么缺少对应的umzug迁移执行记录,要么你的Sequelize开启了自动同步表结构的配置,导致应用启动时尝试重复添加isPublic字段,触发duplicate column name报错。
解决方案
- 在项目根目录创建/更新
.dockerignore文件,添加data/条目,避免本地数据库文件被打包进镜像。 - 执行
docker build --no-cache -t image:tag .重新构建镜像,规避旧缓存层带有的遗留数据库文件。 - 删除已创建的旧命名卷:
docker volume rm appdata,重新创建命名卷后启动容器即可。
内容的提问来源于stack exchange,提问作者Paul Ulibro
相关产品推荐
相关产品推荐

