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命令赋予执行权限:
- 在项目的
src/main/docker目录下创建Dockerfile模板 - 内容如下(基于自动生成的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 []
- 重新执行
sbt docker:publishLocal构建镜像,启动容器即可。
方案3:调整权限策略组合
如果不需要CopyChown策略,可以改用DockerPermissionStrategy.MultiStage,但保留dockerChmodType和dockerAdditionalPermissions:
dockerPermissionStrategy := DockerPermissionStrategy.MultiStage dockerChmodType := DockerChmodType.UserGroupWriteExecute dockerAdditionalPermissions += (DockerChmodType.UserGroupPlusExecute, "/var/run/")
这种方式会在构建阶段处理权限,避免文件所有权问题。
内容的提问来源于stack exchange,提问作者user21236160
相关产品推荐
相关产品推荐

