Skip to content

Commit df6b059

Browse files
respencer-nclclaude
andcommitted
Fix dockerStageProd to flatten numbered staging directories
sbt-native-packager stages files under numbered directories (e.g., 2/opt/docker/lib/, 4/opt/docker/bin/) but the distroless Dockerfile expects them at opt/docker/. Add flattening step to copy files from numbered directories into the expected layout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ac7a8aa commit df6b059

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

src/main/scala/com/ossuminc/sbt/helpers/Packaging.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,29 @@ object Packaging extends AutoPluginHelper {
164164
// First run the normal staging to get lib/ directory
165165
(Docker / stage).value
166166

167+
// sbt-native-packager stages files under numbered directories
168+
// (e.g., 2/opt/docker/lib/, 4/opt/docker/bin/). Flatten them
169+
// into opt/docker/ so the distroless Dockerfile can COPY them.
170+
val flatTarget = stageDir / "opt" / "docker"
171+
IO.createDirectory(flatTarget)
172+
val numberedDirs = stageDir.listFiles().filter { f =>
173+
f.isDirectory && f.getName.forall(_.isDigit)
174+
}
175+
for {
176+
numDir <- numberedDirs
177+
source = numDir / "opt" / "docker"
178+
if source.isDirectory
179+
child <- source.listFiles()
180+
} {
181+
val dest = flatTarget / child.getName
182+
if (child.isDirectory) {
183+
IO.copyDirectory(child, dest)
184+
} else {
185+
IO.copyFile(child, dest)
186+
}
187+
log.info(s"Staged: ${numDir.getName}/opt/docker/${child.getName} -> opt/docker/${child.getName}")
188+
}
189+
167190
// Generate distroless Dockerfile with EXPOSE directives
168191
val dockerfile = stageDir / "Dockerfile"
169192
val exposeLines = ports.map(p => s"EXPOSE $p").mkString("\n")

0 commit comments

Comments
 (0)