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?
3
Answers
Right now only this variant works fine
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:
command
from the question→ adding in your
docker-compose.yml
service definition:entrypoint
andcommand
:→ adding in your
docker-compose.yml
service definition, for instance: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 specificENTRYPOINT
that you want to override, it sounds better to directly modify your ownDockerfile
.Typically, you would write at the end of this file:
Provided you already inserted a command to set the executable bit of your entrypoint, for instance:
For more details on
ENTRYPOINT
andCMD
, see e.g. this other StackOverflow answer:What is the difference between CMD and ENTRYPOINT in a Dockerfile?.
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
/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 changebash
in#!/bin/bash
in your script tosh
orash
.