1

I have a container with node:18-alpine3.14 as base image. I have docker-compose file with

command: ["prepare_config.sh","--","npm", "run", "start-p"]

in prepare config

#!/bin/bash
json_data=$(cat <<EOF
{
    "url": "$URL"
}
EOF
)
echo "$json_data";

When I try to run this code I get error

prepare_config.sh:2
json_data=$(cat <<EOF
                  ^^^

SyntaxError: missing ) after argument list
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Module._load (node:internal/modules/cjs/loader:827:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47

Node.js v18.1.0

Could you help fix that?

ErikMD
  • 13,377
  • 3
  • 35
  • 71
klynxe
  • 65
  • 1
  • 8
  • 1
    It appears your script is not run by `/bin/bash`, but by node (the "entrypoint" of your image). To address your use case, you can "reset the entrypoint", and given you use `docker-compose`, you should just try to add `entrypoint: []` in your `docker-compose.yml` service definition. – ErikMD May 17 '22 at 16:47
  • please feel free to add a bit more details in your question as I suggested [below](https://stackoverflow.com/questions/72277602/cat-in-script-in-docker/72280035?noredirect=1#comment127699116_72277939) (add more details on your Dockerfile; at least the optional `WORKDIR` and the `COPY` commands…) – ErikMD May 17 '22 at 23:05

3 Answers3

2

A quick fix (docker-compose.yml related)

It appears your script is not run by /bin/bash, but by node (the "entrypoint" of your image).

To address your use case, you actually have two equivalent solutions:

  1. "reset the entrypoint" and directly use your command from the question
    → adding in your docker-compose.yml service definition:
myservice:
  entrypoint: []
  command: ["prepare_config.sh", "--", "npm", "run", "start-p"]
  1. set a nonempty entrypoint and command:
    → adding in your docker-compose.yml service definition, for instance:
myservice:
  entrypoint: ["prepare_config.sh", "--"]
  command: ["npm", "run", "start-p"]

Minor remark

As an aside:

  • solution 1. admits an equivalent docker run command:
    docker run --entrypoint="" image-name prepare_config.sh -- npm run start-p

  • but solution 2. does not have an equivalent docker run command, given the CLI option --entrypoint can only take one argument (the program binary), not a list…

A better fix (Dockerfile related)

However, even if your image is based on node:18-alpine3.14 which comes with a specific ENTRYPOINT that you want to override, it sounds better to directly modify your own Dockerfile.

Typically, you would write at the end of this file:

ENTRYPOINT ["prepare_config.sh", "--"]
CMD ["npm", "run", "start-p"]

Provided you already inserted a command to set the executable bit of your entrypoint, for instance:

RUN chmod a+x prepare_config.sh

For more details on ENTRYPOINT and CMD, see e.g. this other StackOverflow answer:
What is the difference between CMD and ENTRYPOINT in a Dockerfile?.

ErikMD
  • 13,377
  • 3
  • 35
  • 71
  • I try to add `ENTRYPOINT ["./prepare_config.sh","--"]` and get very interesting error `standard_init_linux.go:228: exec user process caused: no such file or directory` if I remove this string I won't get this mistake. all my files have LF (I use Ubuntu) this code has the same result `entrypoint: ["prepare_config.sh", "--"] command: ["npm", "run", "start-p"]` – klynxe May 17 '22 at 20:14
  • @klynxe Very good point. If `prepare_config.sh` is not in your PATH, one should use `./prepare_config.sh` or so. I propose to update my answer accordingly, but could you first edit your question to add more details on your Dockerfile? (at least the optional `WORKDIR` and the `COPY` commands…) – ErikMD May 17 '22 at 21:59
0

The entrypoint script in the node container tries to figure out if the command passed to it should be run by node or not.

It does that by checking if the first parameter is a system command or not. Your script is not a system command, so the entrypoint script decides that it should be run by node.

To convince the entrypoint script that your command shouldn't be run by node, you can explicitly say that you want it to be run by the shell like this

command: ["/bin/sh", "-c", "prepare_config.sh -- npm run start-p"]

/bin/sh is a system command, so the entrypoint script won't try to get node to run the command.

Also, be aware that Alpine images usually don't have bash installed, so you might have to change bash in #!/bin/bash in your script to sh or ash.

Hans Kilian
  • 18,948
  • 1
  • 26
  • 35
  • This code start only script, but I can't see logs from npm `command: ["/bin/sh", "-c", "prepare_config.sh -- npm run start-p"]` – klynxe May 17 '22 at 20:23
  • 1
    Your command should probably be `prepare_config.sh && npm run start-p` if you want the script to run and then the npm command afterwards. – Hans Kilian May 17 '22 at 20:26
  • Unless @klynxe adds `exec "$@"` or so at the end of the entrypoint script (after removing the `--` of course), because it's *always* better to try to avoid spinning an extraneous shell (`/bin/sh -c …`). – ErikMD May 17 '22 at 22:01
  • @ErikMD Yeah, but the image is the official `node` image, so that would require that they make their own, custom image. – Hans Kilian May 17 '22 at 22:56
  • @HansKilian are you sure? I don't think the OP uses the official `node` image but already an image *based* on `node` (given the question mentions the `prepare_config.sh` script that is certainly part of the child image(?)) – ErikMD May 17 '22 at 22:57
  • 1
    You're right. I read the first line as if it was the official image. Based on the issue, I'd guess that it's still using the entrypoint from the official image though. – Hans Kilian May 17 '22 at 23:03
0

Right now only this variant works fine

command: ["/bin/sh", "-c", "./prepare_config.sh && npm run start-p"]
klynxe
  • 65
  • 1
  • 8