sbt native packager中Docker COPY本地SQL脚本失败求助
解决多模块SBT项目中Docker COPY本地SQL脚本的路径问题
我来帮你搞定这个头疼的问题——你遇到的核心矛盾是Docker构建上下文的访问限制加上模块内路径引用错误,结合sbt native packager的特性,咱们一步步调整就能解决:
第一步:修正模块内的路径引用
先把最基础的路径问题改对:在database/build.sbt里,baseDirectory.value已经指向了my_sbt/database目录,所以你原本写的baseDirectory.value / "database" / "scripts"多了一层冗余的database,正确的脚本路径应该是baseDirectory.value / "scripts"。
第二步:用sbt原生机制把脚本放入Docker构建上下文
Docker构建时只能读取构建上下文目录内的文件,直接用主机绝对路径传参的话,Docker守护进程根本访问不到上下文外的文件,这就是你报错的核心原因。sbt native packager提供了dockerCopyResources任务,专门用来把本地资源同步到Docker构建上下文(默认是模块的target/docker/stage目录)。
在database/build.sbt中添加这段配置:
// 将scripts目录下的所有SQL脚本复制到Docker上下文的scripts子目录 dockerCopyResources += { val scriptSource = baseDirectory.value / "scripts" val dockerContextDest = stagingDirectory.value / "scripts" (scriptSource ** "*.sql") pair rebase(scriptSource, dockerContextDest) }
第三步:修改dockerCommands使用相对路径COPY
现在脚本已经在Docker构建上下文里了,你只需要用相对路径编写COPY命令即可:
dockerCommands := Seq( Cmd("FROM", "postgres:9.5"), Cmd("EXPOSE", "5432"), // 这里的scripts/a.sql是相对于Docker构建上下文的路径 Cmd("COPY", "scripts/a.sql", "/docker-entrypoint-initdb.d/a.sql") )
验证小技巧:先确认资源是否到位
在构建镜像前,先运行这个命令:
sbt database/docker:stage
然后去my_sbt/database/target/docker/stage/scripts目录看看,如果能看到你的SQL脚本,说明资源复制成功了,再跑sbt docker:publishLocal就不会报错啦。
为啥原来的写法会失败?
- 路径本身错误:你原来的路径指向
my_sbt/database/database/scripts,这个目录根本不存在,自然找不到文件。 - Docker上下文限制:即使路径写对了,直接用主机绝对路径传给Docker,Docker无法访问上下文外的文件,必然报错。
- sbt路径处理逻辑:sbt native packager会自动剥离绝对路径的根目录,进一步导致Docker找不到指定文件。
内容的提问来源于stack exchange,提问作者John Todd
相关产品推荐
相关产品推荐

