sarah w
sarah w

Reputation: 3475

sbt native package manager custom dockerfile:E: Command line option 'O' [from -O] is not understood in combination with the other options

i have an akka-http project i am using sbt-native package manager for creating a dockerfile for it and i need to add some additional commands in my dockerfile for that i am referring to the example given here

here i have commands for downloading Chrome in the container

    FROM ubuntu:20.04

RUN apt-get update; apt-get clean

# Install wget.
RUN apt-get install -y wget

RUN apt-get install -y gnupg

# Set the Chrome repo.
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list

# Install Chrome.
RUN apt-get update && apt-get -y install google-chrome-stable

taken from here is my code in build.sbt

        dockerCommands ++= Seq(
      // setting the run script executable
      ExecCmd("RUN",
    "apt-get",
    "update",
    "apt-get",
    "clean",
    "&&",
    "apt-get",
    "install",
    "-y",
    "wget",
    "&&",
    "apt-get",
    "install",
    "-y",
    "gnupg",
    "&&",
    "wget",
    "-q",
    "-O",
    "-",
    "https://dl-ssl.google.com/linux/linux_signing_key.pub",
  "|",
    "apt-key add",
    "-",
    "&&",
    "echo",
    "deb http://dl.google.com/linux/chrome/deb/ stable main",
    ">>",
    "/etc/apt/sources.list.d/google.list",
  "&&",
    "apt-get","update",
    "&&",
    "apt-get",
    "-y",
    "install",
    "google-chrome-stable")
    )

and docker:stage creates the following dockerfile

FROM ubuntu:20.04
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/notary-scraping"]
CMD []
RUN ["apt-get", "update", "apt-get", "clean", "&&", "apt-get", "install", "-y", "wget", "&&", "apt-get", "install", "-y", "gnupg", "&&", "wget", "-q", "-O", "-", "https://dl-ssl.google.com/linux/linux_signing_key.pub", "|", "apt-key add", "-", "&&", "echo", "deb http://dl.google.com/linux/chrome/deb/ stable main", ">>", "/etc/apt/sources.list.d/google.list", "&&", "apt-get", "update", "&&", "apt-get", "-y", "install", "google-chrome-stable"]

on docker:pubishLocal i am getting this exception

     info] E: Command line option 'O' [from -O] is not understood in combination with the other options.
[info] Removing intermediate container dc789447c7c0
[error] The command 'apt-get update apt-get clean && apt-get install -y wget && apt-get install -y gnupg && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && echo deb http://dl.google.com/linux/chrome/deb/ stable main >> /etc/apt/sources.list.d/google.list && apt-get update && apt-get -y install google-chrome-stable' returned a non-zero code: 100
[error] java.lang.RuntimeException: Nonzero exit value: 100
[error]     at com.typesafe.sbt.packager.docker.DockerPlugin$.publishLocalDocker(DockerPlugin.scala:564)
[error]     at com.typesafe.sbt.packager.docker.DockerPlugin$.$anonfun$projectSettings$37(DockerPlugin.scala:209)
[error]     at com.typesafe.sbt.packager.docker.DockerPlugin$.$anonfun$projectSettings$37$adapted(DockerPlugin.scala:201)
[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.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]     at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
[error]     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]     at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[error]     at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[error]     at java.base/java.lang.Thread.run(Thread.java:834)
[error] (Docker / publishLocal) Nonzero exit value: 100
[error] Total time: 3 s, completed Jun 14, 2023, 4:40:10 PM

what i am doing wrong here?

Upvotes: 1

Views: 538

Answers (1)

Gastón Schabas
Gastón Schabas

Reputation: 3468

If the commands for downloading Chrome in the container are ok, I guess you are missing a ; between apt-get update and apt-get clean. As you already seen, ExecCmd receives a list of String and each command and parameter of the command must be a different string. That's why you write something like

ExecCmd("RUN", "apt-get", "update")

In your case what you did, was put all the commands in just one ExecCmd. Like the following

dockerCommands ++= Seq(
  ExecCmd("RUN",
    "apt-get", "update", // in `commands for downloading Chrome` you have a `;` but not here
    "apt-get", "clean",
    "&&",
    "apt-get", "install", "-y", "wget",
    "&&",
    // ...
  )
)

I think that should solve your issue. Also I suggest to check what's the difference between semicolon and double ampersand in bash. Not sure which one is what you need in this case.

Instead of having all the commands together as a List of Strings, maybe you could use one ExecCmd per command. In that way, it would be easier to read

dockerCommands ++= Seq(
  ExecCmd("RUN", "apt-get", "update")
  ExecCmd("apt-get", "clean")
  ExecCmd("apt-get", "install", "-y", "wget")
  // ...
)

Another approach here could be create a docker image that already has the chrome installed and use it as a base image for the one that you are going to use to pack your app. In that way, you don't need to write commands as Strings inside a List.

Upvotes: 1

Related Questions