For local developer environments I'm ensuring that a mounted node_modules directory is cleared upon every startup via a /bin/sh command, which should be run before the server starts, but after the container is mounted and running.
Desired behavior, NPM script specified should be appended from the "CMD" config or other docker-compose or CLI source
/bin/sh -c "rm -rf /usr/src/app/node_modules/* && npm run start
// OR
/bin/sh -c "rm -rf /usr/src/app/node_modules/* && npm run production
I'm assuming this kind of scripted startup behavior is more common within a .sh file run as the entrypoint, but I'd like to specify the full command from the Dockerfile
My current Dockerfile
ENTRYPOINT ["/bin/sh", "-c", "rm -rf /usr/src/app/node_modules/* && npm run ${exec $@}"]
CMD [ "start" ]
I'm not sure how to handle the escaping of the double-quotes around "$@" within an ENTRYPOINT array.
Currently receiving this output from the container startup
start: 1: start: Bad substitution
CodePudding user response:
I'd highly recommend writing this startup procedure into its own shell script:
#!/bin/sh
# Delete the library tree from the image; we're not going to use it.
rm -rf /usr/src/app/node_modules
# Interpret the command we're given as a specific `npm run` script.
exec npm run "$@"
Now you can COPY
this script in your Dockerfile, and set the ENTRYPOINT
to just run it. Do not use a sh -c
wrapper here.
COPY entrypoint.sh ./
ENTRYPOINT ["./entrypoint.sh"] # in JSON-array syntax
CMD ["start"]
If you're going to inline sh -c
like this, any parameters after the command to run are taken as the positional parameters $0
, $1
, and so on. Normally $0
is the script name (try adding echo "$0"
to the sample script to see what comes out) and with your construction of sh -c
you need to manually supply that parameter.
ENTRYPOINT ["/bin/sh", "-c", "rm -rf node_modules && npm run \"$1\"", "script"]
CMD ["start"]
These arrays use JSON syntax and the quote escaping is the same as in JSON or Javascript.