sbt / sbt-native-packager

sbt Native Packager
https://sbt-native-packager.readthedocs.io/en/stable/
BSD 2-Clause "Simplified" License
1.6k stars 442 forks source link

Docker image with AshScriptPlugin does not run at all #1118

Open mrubin opened 6 years ago

mrubin commented 6 years ago

I have a number of existing Play framework services which I deploy via docker:publishLocal with the default base image. I build on Mac (or Jenkins/linux) and deploy to AWS. I am trying to convert these existing services to the openjdk:8-jre-alpine image. Out of the box, when I just change that base image and also add the AshScriptPlugin, I don't just get is_cygwin warnings (see #978), my services don't run at all:

bin/foo-service: line 51: /opt/docker/lib/foo-service.foo-service-1.0.40-launcher.jar: Permission denied
bin/foo-service: line 56: is_cygwin: not found
Unrecognized option: -J-Xms512M
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

When I modify the build to also install bash into the above Alpine-based image (and do not use AshScriptPlugin), everything is working well. However, I would like to use the stock Alpine base image and not have to install bash.

muuki88 commented 6 years ago

Thanks for your report. This duplicates #978

Can you provide a minimal build.sbt to reproduce this? I wasn't able to reproduce this yet.

mrubin commented 6 years ago

978 only mentions that unnecessary warnings are generated. It seems that the app still runs. My issue is that more that warnings are generated, it seems errors are generated and the project does not run at all.

I have Scala-based Play framework services. They run fine with the below setting in build.sbt:

dockerEntrypoint := Seq("bin/foo-service", "-J-server", "-J-Xms512M", "-J-Xmx3g")

I tried specifying the base image as follows and also adding AshScriptPlugin to enablePlugins():

dockerBaseImage := "openjdk:8-jre-alpine"
dockerEntrypoint := Seq("bin/foo-service", "-J-server", "-J-Xms512M", "-J-Xmx3g")

This setup led to the errors posted above and the project would not run.

I was able to get the project to run by removing AshScriptPlugin and installing bash as follows:

dockerBaseImage := "openjdk:8-jre-alpine"
dockerEntrypoint := Seq("bin/foo-service", "-J-server", "-J-Xms512M", "-J-Xmx3g")

import com.typesafe.sbt.packager.docker._
dockerCommands ++= Seq(
    Cmd("USER", "root"),
    Cmd("RUN", "apk", "--no-cache", "add", "bash"),
    Cmd("USER", "daemon"))
muuki88 commented 6 years ago

Thanks for the additional details. Which sbt-native-packager version are you using? I took a closer look at the errors (always hard on mobile :nerd_face: ).

bin/foo-service: line 51: /opt/docker/lib/foo-service.foo-service-1.0.40-launcher.jar: Permission denied

This error doesn't seem to be related to the AshScriptPlugin, which is confusing why removing it fixes that error. Can you check the permissions in the resulting docker image with and without the AshScriptPlugin ?

Can you also post the result of

$ sbt "show daemonUser in Docker"

bin/foo-service: line 56: is_cygwin: not found

This is the same as in #978 . It seems that the playframework is adding something here.

Unrecognized option: -J-Xms512M

Configuring java options should be done with the javaOptions in Universal setting. E.g.

javaOptions in Universal ++= Seq(
  "-J-Xms512M",
  "-J-Xmx3g"
)

There should also be no need to override the dockerEntrypoint. The javaOptions is the only relevant thing you need to alter in order to achieve.

Hope that helps :smile:

mrubin commented 6 years ago

@muuki88 Thank you for the suggestions. Trying the above I still see:

bin/foo-service: line 51: /opt/docker/lib/foo-service.foo-service-1.0.40-launcher.jar: Permission denied
bin/foo-service: line 56: is_cygwin: not found
Usage: java [-options] class [args...]
...

If I remove AshScriptPlugin and just use the regular bash script, except removing the java options from dockerEntrypoint and putting them into javaOptions in Universal, I don't see any of those options in the generated bash script. Where do they go (from sbt dist)? How can I ensure they're still being applied?

muuki88 commented 5 years ago

Permissions in docker have been completely reworked. Hopefully this is fixed as well.

mrubin commented 5 years ago

Just tried on the latest version (1.4.1) and this is still an issue. When attempting to run the docker image, I get:

$ docker run --rm -it foo-service:1.0.0
/opt/docker/bin/foo-service: line 94: /opt/docker/lib/foo-service.foo-service-1.0.0-launcher.jar: Permission denied
/opt/docker/bin/foo-service: line 99: is_cygwin: not found
Usage: java [-options] class [args...]
           (to execute a class)
   or  java [-options] -jar jarfile [args...]
           (to execute a jar file)

I'm seeing that the jar files at /opt/docker/lib have -r--r--r-- permissions.

Line 94 of /opt/docker/bin/foo-service is the following:

app_mainclass=-jar "$lib_dir/foo-service.chat-service-1.0.0-launcher.jar"

muuki88 commented 5 years ago

Can you give a build.sbt to reproduce this? Even better a pull request with a failing test?

There's an extensive test-suite in src/sbt-test/docker/file-permission that you can use as an inspiration to write a new test in the src/sb-test/ash/ directory.