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?
CodePudding user response:
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:
- "reset the entrypoint" and directly use your
command
from the question
→ adding in yourdocker-compose.yml
service definition:
myservice:
entrypoint: []
command: ["prepare_config.sh", "--", "npm", "run", "start-p"]
- set a nonempty
entrypoint
andcommand
:
→ adding in yourdocker-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?.
CodePudding user response:
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
.
CodePudding user response:
Right now only this variant works fine
command: ["/bin/sh", "-c", "./prepare_config.sh && npm run start-p"]