仅通过Dockerfile构建含已恢复备份的SQL Server镜像并删除冗余备份文件
可行实现方案
完全可以仅通过Dockerfile配合docker build命令实现需求,核心是利用Docker BuildKit的构建时临时挂载特性,备份文件全程不会写入镜像层,自然不需要后续删除操作。
前置说明
目前主流Docker版本默认已开启BuildKit,若构建时出现挂载语法不支持的问题,可在构建命令前加DOCKER_BUILDKIT=1手动启用。
调整后的Dockerfile
# syntax=docker/dockerfile:1.2 FROM mcr.microsoft.com/mssql/server:2019-latest ENV MSSQL_PID=Developer ENV SA_PASSWORD=Password1? ENV ACCEPT_EULA=Y USER mssql # 启动SQL Server,确认启动完成后恢复数据库,再终止SQL Server进程 RUN --mount=type=bind,source=./rmsdev.bak,target=/var/opt/mssql/backup/rmsdev.bak,readonly \ ( /opt/mssql/bin/sqlservr & ) | grep -q "Service Broker manager has started" \ && /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA_PASSWORD -Q 'RESTORE DATABASE rmsdev FROM DISK = "/var/opt/mssql/backup/rmsdev.bak" WITH MOVE "rmsdev" to "/var/opt/mssql/data/rmsdev.mdf", MOVE "rmsdev_Log" to "/var/opt/mssql/data/rmsdev_log.ldf", NOUNLOAD, STATS = 5' \ && pkill sqlservr CMD ["/opt/mssql/bin/sqlservr"]
关键改动说明
- 删掉了原来的
COPY指令,避免备份文件写入镜像层 - 在
RUN指令前增加了--mount参数,构建执行该RUN指令时,会临时将本地存放的rmsdev.bak挂载到容器内指定路径,仅对当前RUN步骤可见,执行完自动销毁,不会在镜像中留下任何痕迹 - 开头的
# syntax=docker/dockerfile:1.2用来指定Dockerfile语法版本,确保挂载特性被正常识别
构建命令
直接执行常规构建命令即可:
docker build . -t mssql-rmsdev:latest
若未默认开启BuildKit,使用如下命令:
DOCKER_BUILDKIT=1 docker build . -t mssql-rmsdev:latest
效果验证
构建完成后启动容器,可进入容器内查看/var/opt/mssql/backup/路径,不存在rmsdev.bak文件,同时rmsdev数据库可正常访问使用。
替代方案(无BuildKit场景)
如果使用的Docker版本过旧不支持BuildKit,可将备份文件上传到内部可访问的HTTP存储地址,在同一条RUN指令内完成全流程操作,不会残留备份文件:
FROM mcr.microsoft.com/mssql/server:2019-latest ENV MSSQL_PID=Developer ENV SA_PASSWORD=Password1? ENV ACCEPT_EULA=Y USER mssql RUN ( /opt/mssql/bin/sqlservr & ) | grep -q "Service Broker manager has started" \ # 下载备份文件 && wget -O /var/opt/mssql/backup/rmsdev.bak http://内部文件服务地址/rmsdev.bak \ && /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P $SA_PASSWORD -Q 'RESTORE DATABASE rmsdev FROM DISK = "/var/opt/mssql/backup/rmsdev.bak" WITH MOVE "rmsdev" to "/var/opt/mssql/data/rmsdev.mdf", MOVE "rmsdev_Log" to "/var/opt/mssql/data/rmsdev_log.ldf", NOUNLOAD, STATS = 5' \ # 删除备份文件 && rm -f /var/opt/mssql/backup/rmsdev.bak \ && pkill sqlservr CMD ["/opt/mssql/bin/sqlservr"]
这种方案所有文件操作都在同一个RUN层内完成,删除后的文件不会残留在镜像中,但需要额外的文件存储服务支撑,优先级低于BuildKit方案。
内容的提问来源于stack exchange,提问作者Franco Tiveron
相关产品推荐
相关产品推荐

