You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

sbt-native-packager构建Docker镜像启动容器遇权限拒绝错误求助

sbt-native-packager权限配置导致Docker容器启动权限拒绝问题

环境与问题复现

  • 使用IntelliJ IDEA,通过sbt-native-packager插件构建Docker镜像,执行命令:
    sbt> docker:publishLocal
    
  • 镜像创建成功,执行docker images可见:
    student                0.0.3     aecb0ddf2593   12 minutes ago   662MB
    
  • 插件自动生成的Dockerfile:
    FROM openjdk:8
    USER root
    RUN id -u demiourgos728 1>/dev/null 2>&1 || (( getent group 0 1>/dev/null 2>&1 || ( type groupadd 1>/dev/null 2>&1 && groupadd -g 0 root || addgroup -g 0 -S root )) && ( type useradd 1>/dev/null 2>&1 && useradd --system --create-home --uid 1001 --gid 0 demiourgos728 || adduser -S -u 1001 -G root demiourgos728 ))
    WORKDIR /opt/docker
    COPY --chown=demiourgos728:root opt /opt
    EXPOSE 8083
    USER 1001:0
    ENTRYPOINT ["/opt/docker/bin/student"]
    CMD []
    
  • 使用Docker Compose(version 3)启动,student-docker.yml配置:
    version: "3"
    
    services:
      student-database-container:
        container_name: student-container
        image: student:0.0.3
        ports:
          - 8083:8083
        networks:
          - web
    
    networks:
      web:
        driver: bridge
    
  • 执行docker compose -f student-docker.yml up时出现错误:
    [+] Running 1/0
     ✔ Container student-container  Created                                                                                                           0.1s 
    Attaching to student-container
    Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: eaccess /opt/docker/bin/student: permission denied: unknown
    
  • 执行docker ps -a可见容器已创建但未启动:
    aecb0ddf2593   student:0.0.3                "/opt/docker/bin/stu…"   12 minutes ago   Created                      0.0.0.0:8083->8083/tcp, :::8083->8083/tcp   student-container
    
  • build.sbt配置(移除以下配置后容器可正常运行):
    import com.typesafe.sbt.packager.docker.{Cmd, DockerChmodType, DockerPermissionStrategy, ExecCmd}
    
    lazy val root = (project in file("."))
      .settings(
        name := "student"
      )
    
    ThisBuild / version := "0.1.0-SNAPSHOT"
    
    ThisBuild / scalaVersion := "2.13.1"
    
    enablePlugins(JavaAppPackaging, DockerPlugin)
    packageName in Docker:= "student"
    
    version in Docker:= "0.0.1"
    dockerExposedPorts:= Seq(8083)
    
    dockerChmodType := DockerChmodType.UserGroupWriteExecute
    dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
    dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")
    
    libraryDependencies ++= Seq(
      "com.typesafe" % "config" % "1.3.0",
      "com.typesafe.akka" %% "akka-actor" % "2.6.0",
      "com.typesafe.akka" %% "akka-stream" % "2.7.0",
      "com.typesafe.akka" %% "akka-http" % "10.5.0",
      "ch.qos.logback" % "logback-classic" % "1.3.5"
    )
    
    需要保留的权限配置:
    dockerChmodType := DockerChmodType.UserGroupWriteExecute
    dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
    dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")
    

问题原因

配置DockerPermissionStrategy.CopyChown后,COPY命令会将文件所有权改为demiourgos728:root,但dockerChmodType设置的UserGroupWriteExecute未确保启动脚本/opt/docker/bin/student拥有执行权限,导致非root用户无法执行该脚本。

解决方案

方案1:添加启动脚本的执行权限配置

在build.sbt中补充对启动脚本目录的权限设置,确保脚本拥有执行权限:

dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/opt/docker/bin/")

完整的权限配置部分变为:

dockerChmodType := DockerChmodType.UserGroupWriteExecute
dockerPermissionStrategy := DockerPermissionStrategy.CopyChown
dockerAdditionalPermissions ++= Seq(
  (DockerChmodType.UserGroupPlusExecute, "/var/run/"),
  (DockerChmodType.UserGroupPlusExecute, "/opt/docker/bin/")
)

重新构建镜像并启动容器即可。

方案2:自定义Dockerfile模板添加chmod命令

如果方案1不生效,可以自定义Dockerfile模板,在COPY后手动添加chmod命令赋予执行权限:

  1. 在项目的src/main/docker目录下创建Dockerfile模板
  2. 内容如下(基于自动生成的Dockerfile修改):
FROM openjdk:8
USER root
RUN id -u demiourgos728 1>/dev/null 2>&1 || (( getent group 0 1>/dev/null 2>&1 || ( type groupadd 1>/dev/null 2>&1 && groupadd -g 0 root || addgroup -g 0 -S root )) && ( type useradd 1>/dev/null 2>&1 && useradd --system --create-home --uid 1001 --gid 0 demiourgos728 || adduser -S -u 1001 -G root demiourgos728 ))
WORKDIR /opt/docker
COPY --chown=demiourgos728:root opt /opt
# 手动添加执行权限
RUN chmod ug+x /opt/docker/bin/student
EXPOSE 8083
USER 1001:0
ENTRYPOINT ["/opt/docker/bin/student"]
CMD []
  1. 重新执行sbt docker:publishLocal构建镜像,启动容器即可。

方案3:调整权限策略组合

如果不需要CopyChown策略,可以改用DockerPermissionStrategy.MultiStage,但保留dockerChmodType和dockerAdditionalPermissions:

dockerPermissionStrategy := DockerPermissionStrategy.MultiStage
dockerChmodType := DockerChmodType.UserGroupWriteExecute
dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")

这种方式会在构建阶段处理权限,避免文件所有权问题。


内容的提问来源于stack exchange,提问作者user21236160

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 08:54:55