Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker Entrypoint does not consider mainClass option (and resulted script name) #1335

Closed
lebenitza opened this issue Apr 30, 2020 · 12 comments
Closed
Labels

Comments

@lebenitza
Copy link

Expected behaviour

I have a project with multiple main classes and as state here: https://www.scala-sbt.org/sbt-native-packager/archetypes/java_app/index.html#usage I use

mainClass in(Compile, run) := Option("com.<redacted>.Boot")

The scripts in bin result with boot name which I think is to be expected.

Building the docker image for the project I expect the image to start properly.

Actual behaviour

The Entrypoint in the image is wrong, using project name and not considering the given mainClass option.

From docker inspect

ENTRYPOINT [\"/opt/microservice/bin/<project-name>\"]

Information

Plugin version: 1.7.0
SBT: 1.3.10
Built on Linux

Related options:

val dockerSettings = Seq(
  defaultLinuxInstallLocation in Docker := "/opt/microservice",
  dockerRepository in Docker := Some("<docker-registry>"),
  dockerExposedPorts in Docker := Seq(8080),
  // Ignore this, we need to run as root for now
  daemonUser in Docker := "root",
  daemonUserUid in Docker := None,
  version in Docker := version.value
)
@muuki88 muuki88 added bug docker and removed bug labels May 4, 2020
@muuki88
Copy link
Contributor

muuki88 commented May 4, 2020

Thanks @MihaiAnei for the detailed issue report 😃

The entrypoint is build from the Docker / defaultLinuxInstallationLocation (defined here setting that you configured and the executableScriptName (defined here.

If you have multiple scripts then there are two configuration options described in the multiple start scripts documentation.

Can you post the error message from the docker image? A small build setup reproducing this error would be perfect too 😄

@lebenitza
Copy link
Author

Hey @muuki88,
This is inside the docker image resulted from the above settings:

/opt/microservice/bin # ls
boot                  boot.bat              loader-generator      loader-generator.bat

Those have exactly the name of the two main classes I have in the project.

            "Cmd": [],
            "Image": "sha256:417ebed96c1c6ee7d7de9cd2b19ee1ae13ed699ac3426c78e5cc8c814d779f0f",
            "Volumes": null,
            "WorkingDir": "/opt/microservice",
            "Entrypoint": [
                "/opt/microservice/bin/my-project"
            ],

as you can see the entrypoint is pointing to the values of name := "my-project" instead of the name of the resulted script of this mainClass in(Compile, run) := Option("com.<redacted>.Boot").

I think a simple project with 2 main classes one of which is used in build.sbt and then running docker:publishLocal would do the trick.

I can try to provide an example project if that helps you better :)

@muuki88
Copy link
Contributor

muuki88 commented May 4, 2020

Thanks for the feedback 😃

Can you post the output of

$ sbt "inspect dockerEntrypoint" "inspect tree dockerEntrypoint"

Somewhere the executableScriptname is being messed up. I'm not sure where the my-project is coming from.

@muuki88
Copy link
Contributor

muuki88 commented May 4, 2020

And yes. Two modules will do the trick 👍

@lebenitza
Copy link
Author

Here is an example reproducing it: https://github.com/MihaiAnei/sbt-native-packager-1335

❯ sbt "inspect dockerEntrypoint" "inspect tree dockerEntrypoint"
[info] Loading settings for project sbt-native-packager-1335-build from plugins.sbt,license.sbt ...
[info] Loading project definition from /home/<redacted>/sbt-native-packager-1335/project
[info] Loading settings for project sbt-native-packager-1335 from build.sbt ...
[info] Set current project to sbt-native-packager-1335 (in build file:/home/<redacted>/sbt-native-packager-1335/)
[info] Setting: scala.collection.Seq[java.lang.String] = List(/opt/microservice/bin/sbt-native-packager-1335)
[info] Description:
[info]  Entrypoint arguments passed in exec form
[info] Provided by:
[info]  ProjectRef(uri("file:/home/<redacted>/sbt-native-packager-1335/"), "sbt-native-packager-1335") / dockerEntrypoint
[info] Defined at:
[info]  (com.typesafe.sbt.packager.docker.DockerPlugin.projectSettings) DockerPlugin.scala:123
[info] Dependencies:
[info]  executableScriptName
[info]  Docker / defaultLinuxInstallLocation
[info] Reverse dependencies:
[info]  dockerCommands
[info] Delegates:
[info]  dockerEntrypoint
[info]  ThisBuild / dockerEntrypoint
[info]  Global / dockerEntrypoint
[info] dockerEntrypoint = List(/opt/microservice/bin/sbt-native-packager-1335)
[info]   +-Docker / defaultLinuxInstallLocation = /opt/microservice
[info]   +-executableScriptName = sbt-native-packager-1335
[info]     +-normalizedName = sbt-native-packager-1335
[info]       +-name = sbt-native-packager-1335
[info]       
      

Above command's output for it.

So it's either the script name that needs to be fixed or the entrypoint value?!

@muuki88
Copy link
Contributor

muuki88 commented May 4, 2020

Thanks for the test project. I'll take a look tomorrow. From a first glance this could be an issue with the AshScriptPlugin.

You could try without the AshScriptPlugin until I take a look.

@lebenitza
Copy link
Author

Thanks for looking into this!
I tried with

  .enablePlugins(JavaAppPackaging)
  .enablePlugins(DockerPlugin)

but still the same :(

@muuki88
Copy link
Contributor

muuki88 commented May 5, 2020

Hi @MihaiAnei

So I checked out the project and called

$ sbt docker:stage

and opened the docker file in target/docker/stage/Dockerfile. The content looks as expected:

FROM openjdk:8 as stage0
LABEL snp-multi-stage="intermediate"
LABEL snp-multi-stage-id="61cc79ce-cf84-4f02-9c53-c4822a2e68ac"
WORKDIR /opt/microservice
COPY 1/opt /1/opt
COPY 2/opt /2/opt
USER root
RUN ["chmod", "-R", "u=rX,g=rX", "/1/opt/microservice"]
RUN ["chmod", "-R", "u=rX,g=rX", "/2/opt/microservice"]
RUN ["chmod", "u+x,g+x", "/1/opt/microservice/bin/boot"]
RUN ["chmod", "u+x,g+x", "/1/opt/microservice/bin/loader-generator"]

FROM openjdk:8
WORKDIR /opt/microservice
COPY --from=stage0 --chown=root:root /1/opt/microservice /opt/microservice
COPY --from=stage0 --chown=root:root /2/opt/microservice /opt/microservice
USER root
ENTRYPOINT ["/opt/microservice/bin/sbt-native-packager-1335"]
CMD []

How does your Dockerfile look like? How did you call the docker inspect command. Maybe you referenced another image than the one you built?

@lebenitza
Copy link
Author

Well, that's the problem

ENTRYPOINT ["/opt/microservice/bin/sbt-native-packager-1335"]

does not exist in bin/. In stage0 we can see there are 2 scripts generated

RUN ["chmod", "u+x,g+x", "/1/opt/microservice/bin/boot"]
RUN ["chmod", "u+x,g+x", "/1/opt/microservice/bin/loader-generator"]

none with that name in entry point. Try a publish local and a docker run --rm -it image-name:tag

@lebenitza
Copy link
Author

There is also a commented out workaround in built.sbt :)

@muuki88
Copy link
Contributor

muuki88 commented May 6, 2020

Thanks for your patience @MihaiAnei 😅 Of course that's the issue 🤦

I found the root cause. It's, as quite a few times, a scoping issue. So the fix ist

// too narrow scope
Comile / run / mainClass := Some("...")

// just about right scope
Compile / mainClass := Some("....") 

the mainClass in (Compile,run) (I used the new syntax in the example above) isn't used for setting the executableScriptName . So it falls back to the default behaviour.

The default behaviour, generating a script per class, doesn't work very well with the docker plugin. However I'm fine with that as a docker image ideally as one entry point. IMHO that's the point of having containers 😜 If you have multiple main classes, then setting the "default" one should be fine.

Thanks again for your help 😗

@muuki88 muuki88 closed this as completed May 6, 2020
@lebenitza
Copy link
Author

Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants