Alexander Mills
Alexander Mills

Reputation: 100320

Add arguments to entrypoint/cmd for different containers

I have this simple node.js image:

FROM node:12

USER root

WORKDIR /app

COPY package.json .
COPY package-lock.json .

RUN npm i --production

COPY . .

ENTRYPOINT node dist/main.js

ultimately, I just want to be able to pass different arguments to node dist/main.js like so:

docker run -d my-image --foo --bar=3

so that the executable when run is

node dist/main.js --foo --bar=3

I have read about CMD / ENTRYPOINT and I don't know how to do this, anybody know?

Upvotes: 0

Views: 1449

Answers (2)

Alexander Mills
Alexander Mills

Reputation: 100320

This seems to work:

ENTRYPOINT ["node", "dist/main.js"]
CMD []

which appears to be equivalent to just:

ENTRYPOINT ["node", "dist/main.js"]

you can't seem to use single quotes - double quotes are necessary, and you have to use shell syntax..not sure why, but this style does not work:

ENTRYPOINT node dist/main.js

Upvotes: 1

David Maze
David Maze

Reputation: 159830

I would suggest writing a custom entrypoint script to handle this case.

In general you might find it preferable to use CMD to ENTRYPOINT in most cases. In particular, the debugging shell pattern of

docker run --rm -it myimage sh

is really useful, and using ENTRYPOINT to run your main application breaks this. The entrypoint script pattern I’m about to describe is also really useful in general and it’s easy to drop in if your main container process is described with CMD.

ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["node", "dist/main.js"]

The script itself is an ordinary shell script that gets passed the CMD as command-line arguments. It will typically end with exec "$@" to actualy run the CMD as the main container process.

Since the entrypoint script is a shell script, and it gets passed the command from the docker run command line as arguments, you can do dynamic switching on it, and meet both your requirement to just be able to pass additional options to your script and also my requirement to be able to run arbitrary programs instead of the Node application.

#!/bin/sh
if [ $# = 1 ]; then
  # no command at all
  exec node dist/main.js
else
  case "$1" of
  -*) exec node dist/main.js "$@" ;;
  *)  exec "$@" ;;
  esac
fi

Upvotes: 1

Related Questions