【问题标题】:How to create a Docker image of a Scala Play application using jre-alpine base image如何使用 jre-alpine 基础镜像创建 Scala Play 应用程序的 Docker 镜像
【发布时间】:2019-12-21 23:26:28
【问题描述】:

我想利用jre-alpine Docker 基础镜像来缩小我必须推送到我的 Docker 注册表的 docker 镜像的大小,但我经常遇到这个错误:

[info] Step 10/16 : RUN id -u demiourgos728 2> /dev/null || useradd --system --create-home --uid 1001 --gid 0 demiourgos728
[info]  ---> Running in 696dcf40530a
[info] /bin/sh: useradd: not found
[info] Removing intermediate container 696dcf40530a
[error] The command '/bin/sh -c id -u demiourgos728 2> /dev/null || useradd --system --create-home --uid 1001 --gid 0 demiourgos728' returned a non-zero code: 127
[error] java.lang.RuntimeException: Nonzero exit value: 127
[error]     at com.typesafe.sbt.packager.docker.DockerPlugin$.publishLocalDocker(DockerPlugin.scala:483)
[error]     at com.typesafe.sbt.packager.docker.DockerPlugin$.$anonfun$projectSettings$33(DockerPlugin.scala:187)
[error]     at com.typesafe.sbt.packager.docker.DockerPlugin$.$anonfun$projectSettings$33$adapted(DockerPlugin.scala:185)
[error]     at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error]     at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:40)
[error]     at sbt.std.Transform$$anon$4.work(System.scala:67)
[error]     at sbt.Execute.$anonfun$submit$2(Execute.scala:269)
[error]     at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error]     at sbt.Execute.work(Execute.scala:278)
[error]     at sbt.Execute.$anonfun$submit$1(Execute.scala:269)
[error]     at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178)
[error]     at sbt.CompletionService$$anon$2.call(CompletionService.scala:37)
[error]     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error]     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error]     at java.lang.Thread.run(Thread.java:748)
[error] (Docker / publishLocal) Nonzero exit value: 127

涉及的版本:

  • 播放 2.7.3
  • Scala 2.12.8
  • Docker 19.03.1
  • sbt 1.2.8

在我的 build.sbt 中我添加了:

enablePlugins(AshScriptPlugin)
dockerBaseImage := "openjdk:jre-alpine"

按照此处提供的说明进行操作:https://www.scala-sbt.org/sbt-native-packager/formats/docker.html#busybox-ash-support

Play 尝试执行的 Docker 命令:

show dockerCommands
[info] Wrote /Users/xxxxx/projects/together/togrx/target/scala-2.12/together-rx_2.12-0.7.0-a.pom
[info] * Cmd(FROM,WrappedArray(openjdk:8-jre-alpine, as, stage0))
[info] * Cmd(WORKDIR,WrappedArray(/opt/docker))
[info] * Cmd(COPY,WrappedArray(opt /opt))
[info] * Cmd(USER,WrappedArray(root))
[info] * ExecCmd(RUN,List(chmod, -R, u=rX,g=rX, /opt/docker))
[info] * ExecCmd(RUN,List(chmod, u+x,g+x, /opt/docker/bin/together-rx))
[info] * DockerStageBreak
[info] * Cmd(FROM,WrappedArray(openjdk:8-jre-alpine))
[info] * Cmd(USER,WrappedArray(root))
[info] * Cmd(RUN,List(id, -u, demiourgos728, 2>, /dev/null, ||, useradd, --system, --create-home, --uid, 1001, --gid, 0, demiourgos728))
[info] * Cmd(WORKDIR,WrappedArray(/opt/docker))
[info] * Cmd(COPY,WrappedArray(--from=stage0 --chown=demiourgos728:root /opt/docker /opt/docker))
[info] * Cmd(EXPOSE,WrappedArray(4300 4301))
[info] * Cmd(USER,WrappedArray(1001))
[info] * ExecCmd(ENTRYPOINT,List(/opt/docker/bin/together-rx))
[info] * ExecCmd(CMD,List())

【问题讨论】:

    标签: docker playframework sbt-native-packager


    【解决方案1】:

    alpine 镜像中没有useradd 命令,请改用adduser,见下:

    $ docker run -it openjdk:jre-alpine /bin/sh
    Unable to find image 'openjdk:jre-alpine' locally
    jre-alpine: Pulling from library/openjdk
    [DEPRECATION NOTICE] registry v2 schema1 support will be removed in an upcoming release. Please contact admins of the docker.io registry NOW to avoid future disruption.
    8e3ba11ec2a2: Pull complete
    311ad0da4533: Pull complete
    391a6a6b3651: Pull complete
    Digest: sha256:016a7989474f1e685da966631ba6403cb349548621ebb8e4a6205f7c5fa88320
    Status: Downloaded newer image for openjdk:jre-alpine
    / # useradd
    /bin/sh: useradd: not found
    / # echo $?
    127
    / # adduser
    BusyBox v1.28.4 (2018-05-30 10:45:57 UTC) multi-call binary.
    
    Usage: adduser [OPTIONS] USER [GROUP]
    
    Create new user, or add USER to GROUP
    
            -h DIR          Home directory
            -g GECOS        GECOS field
            -s SHELL        Login shell
            -G GRP          Group
            -S              Create a system user
            -D              Don't assign a password
            -H              Don't create home directory
            -u UID          User id
            -k SKEL         Skeleton directory (/etc/skel)
    / #
    

    因此,您需要修改build.sbt 或其他内容以确保使用adduser 而不是useradd

    更新:

    如你所说,useradd是play framework生成的,那么我建议你自定义自己的图片添加useradd,它在shadow包中,那么play framework就透明了,像下一个:

    Dockerfile:

    FROM openjdk:jre-alpine
    
    RUN apk add shadow
    

    在本地 docker 主机中构建映像:

    docker build -t myimage .
    

    最后,在 build.sbt 中:

    dockerBaseImage := "myimage"
    

    【讨论】:

    • 你知道我应该如何修改那个命令吗?我猜有一个文件定义了这些命令。
    • 这个项目不是你写的? grep -rn "useradd" * 找不到?我猜通常它在 build.sbt、Build.scala 等东西中。
    • 我自己编写了应用程序,但该命令来自 Play 框架 2.7.3。
    • 我正在尝试测试您的解决方案,但问题是我必须从头开始重写所有命令才能使用 dockerCommands += Cmd("RUN","apk add shadow") 在正确的位置添加“阴影”=> @987654322 @
    • 不,你不需要那样做。您可以认为 myimage 是您构建之外的基础设施,与 scala 代码无关。你只需构建这个镜像,并在 build.sbt 中指定它dockerBaseImage := "myimage"。我猜当你做dockerBaseImage := openjdk:jre-alpine时,插件会从dockerhub下载openjdk:jre-alpine,现在你只需使用你自己的图像,其中预装了useradd
    猜你喜欢
    • 2017-04-24
    • 1970-01-01
    • 2015-02-15
    • 2017-09-29
    • 2020-01-20
    • 2015-11-09
    • 2015-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多