Dockerfile COPY db.bak到容器挂载目录后文件不存在问题
问题原因
Dockerfile中的COPY指令实际已经执行成功,构建阶段db.bak确实被写入了镜像内的/var/opt/mssql/backup/路径。
文件找不到的核心原因是:docker-compose.yml中配置的绑定挂载./volume_backup:/var/opt/mssql/backup会在容器启动阶段生效,直接将宿主机的./volume_backup目录挂载到容器内的对应路径,完全覆盖镜像构建阶段写入该路径的所有内容。你本地的volume_backup目录初始是空的,所以容器启动后该路径下自然找不到构建时复制进去的db.bak。
解决方案
你可以根据自己的需求任选以下一种方案修复:
- 方案1:保留挂载配置,调整文件复制逻辑
修改Dockerfile,先将db.bak复制到镜像内不会被挂载覆盖的临时路径,在容器启动脚本中判断挂载目录下不存在备份文件时,自动将临时路径的文件复制到挂载目录,再执行数据库还原和服务启动操作。参考配置如下:
该方案首次启动会自动完成备份文件初始化,后续宿主机挂载目录的文件修改也会正常同步到容器内。FROM mcr.microsoft.com/mssql/server:2019-latest ENV ACCEPT_EULA=Y ENV MSSQL_SA_PASSWORD=Abc@123456 USER root # 备份文件先存到临时目录,避开挂载覆盖路径 COPY db.bak /tmp/init/ # 编写启动执行脚本 RUN printf '#!/bin/bash\nif [ ! -f /var/opt/mssql/backup/db.bak ]; then\n cp /tmp/init/db.bak /var/opt/mssql/backup/\nfi\n/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -Q "RESTORE DATABASE Lion FROM DISK = \"/var/opt/mssql/backup/db.bak\" WITH MOVE \"SRLM\" TO \"/var/opt/mssql/data/SRLM.mdf\", MOVE \"SRLM_Log\" TO \"/var/opt/mssql/data/SRLM.ldf\" & /opt/mssql/bin/sqlservr' > /tmp/start.sh && chmod +x /tmp/start.sh CMD ["/bin/bash", "/tmp/start.sh"] - 方案2:移除对应路径的绑定挂载
如果不需要在宿主机直接访问容器内的备份目录,直接删除docker-compose.yml中volumes配置段下的- ./volume_backup:/var/opt/mssql/backup行即可,构建时复制到镜像内的文件不会被覆盖,容器启动后可直接读取。
注意:该方案下容器内/var/opt/mssql/backup/路径的文件不会持久化到宿主机,容器删除后该路径下的内容会随容器一起清除。 - 方案3:直接将备份文件放到宿主机挂载目录
你已经验证过手动将db.bak放到宿主机volume_backup目录后还原可正常执行,这种方式不需要修改镜像和编排配置,部署时提前将备份文件放到宿主机对应目录即可。
内容的提问来源于stack exchange,提问作者Alfred Luu
相关产品推荐
相关产品推荐

