1

(update from 14th Nov 14:25: This question can be closed as it faces multiple issues and should not be confused with each other. Later on I will come back and add the reference to the more specific question.

Inspired by https://stackoverflow.com/a/39408777 I made an table of possible cases and was able to find identify 2 isolated cases:

+------------------+-------------------------------------------+------------------------+---------------------------------------------------+
|                  | No Entrypoint                             | Entrypoint (JSON-form) | Entrypoint (shell-form)                           |
+------------------+-------------------------------------------+------------------------+---------------------------------------------------+
| No CMD           | HostConfig.Config.cmd=/bin/bash is called | breaks                 | ok                                                |
|                  | (assumption as of docker inspect)         | (See Case 1)           |                                                   |
+------------------+-------------------------------------------+------------------------+---------------------------------------------------+
| CMD (JSON-form)  | breaks(See Case 1)                        | breaks                 | breaks                                            |
|                  |                                           | (See Case 1)           | (See Case 2)                                      |
+------------------+-------------------------------------------+------------------------+---------------------------------------------------+
| CMD (shell-form) | ok                                        | ok                     | Breaks [seems to work as designed]                |
|                  |                                           |                        | (both are called with a shell concatinated)       |
|                  |                                           |                        | Example: /bin/sh -c <ENTRYPOINT> /bin/sh -c <CMD> |
+------------------+-------------------------------------------+------------------------+---------------------------------------------------+

Case 1 – escaping issue of double quotes for the exec form. Possible workarounds: Create a separate shell script and handle all the logic within this script.

Case 2 - Parameter of CMD in exec form get lost if used with Entrypoint

( used wording:

  • exec form using json array -> CMD["command", "parameter"]
  • shell form -> CMD command parameter

see: https://docs.docker.com/engine/reference/builder/#cmd )

(update from 14th Nov 12:16: I tried to reproduce this behavior with ubuntu:latest and faced a different behavior with bash and dash. After some trial and error I can say that it works in the shellform for both - ENTRYPOINT and CMD. I will investigate further what happens when I make use of the jsonform. The escape directive didn't changed the behavior)

my question is not focusing on the decision making when to use ENTRYPOINT or CMD but more how it behaves when it comes to the pass-through of the parameter to the container. But t.b.h. I'm not sure if this is a docker or alpine environment / shell related question -> tagged both.

Expected behavior

Use ENTRYPOINT to set stable default command and arguments and use CMD to set overwritable parameter. Those parameter are then passed through correctly to the container.

Actual behavior

The called executable behaves differently in three different scenarios. Each three cases will be described below.


Case 1: Parameter are passed through as expected. But I wasn't able to achive it with ENTRYPOINT. Only CMD.

Case 2: Combination of ENTRYPOINT and CMD. Two chars "/" with unknown source appear.

Case 3: Combination of ENTRYPOINT (shell form) and CMD. Parameter from CMD seem to vanish.

Obervations to fix Case 3 with an interactive shell (docker exec -it --entrypoint="/bin/bash"): escape all parameter with a single quote from

/bin/sh -c /usr/bin/run.sh server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"

to

/bin/sh -c '/usr/bin/run.sh server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"'

But why does it work in Case 1 with CMD only? And the SHLVL is set to the value '2'.


What I've tried so far

  • diff the docker inspect output of relevant container -> nothing suspicious for me (can be posted if required)
  • wrote a simple wrapper script to print environment variables, ps faux and parameter passed through. (output below)
  • Read online articles (e.g. Dockerfile reference and https://stackoverflow.com/a/39408777 (possible combinations of ENTRYPOINT and CMD))

Source of referenced run.sh -> link:

Command used to build an run the container:

"sudo docker build -t docker-hugo . && sudo docker run --rm docker-hugo"

#Dockerfile CASE 1 - Works but without ENTRYPOINT (what I like to achieve):

FROM alpine:latest
RUN apk --no-cache add hugo
CMD hugo server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"

Relevant output:

Error: Unable to locate Config file. Perhaps you need to create a new site.
       Run `hugo help new` for details. (Config File "config" Not Found in "[/src]") <-- "/src" as provided via CMD

Command within Container (achieved via "ps faux" and docker exec -it --entrypoint="/bin/ash")

PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh -c hugo server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"
    7 root       0:00 hugo server --watch=true --bind=0.0.0.0 --source=/src --destination=/output
   28 root       0:00 ash
   34 root       0:00 ps faux

#Dockerfile CASE 2 - Don't understand where the "/" from the stdout is coming from FROM alpine:latest RUN apk --no-cache add hugo #ENTRYPOINT ["/usr/bin/run.sh"] ENTRYPOINT ["hugo"] CMD ["server", "--watch=true", "--bind=0.0.0.0", "--source="/src"", "--destination="/output""]

Relevant output:

Error: Unable to locate Config file. Perhaps you need to create a new site.
       Run `hugo help new` for details. (Config File "config" Not Found in "[/\"/src\"]")   <-- where is the "/\" coming from?)

Command and environment from container (stdout from run.sh)

HOME='/root'
HOSTNAME='805e3dd6110a'
IFS='   
'
OPTIND='1'
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PPID='0'
PS1='\w \$ '
PS2='> '
PS4='+ '
PWD='/'
SHLVL='1'

PID   USER     TIME   COMMAND
    1 root       0:00 ash /usr/bin/run.sh server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"
    7 root       0:00 ps faux

server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"

#Dockerfile CASE 3 - Not OK - CMD Parameter seem to "vanish"

FROM alpine:latest
RUN apk --no-cache add hugo
#ENTRYPOINT ["/usr/bin/run.sh"]
ENTRYPOINT /usr/bin/run.sh
CMD ["server", "--watch=true", "--bind=0.0.0.0", "--source=\"/src\"", "--destination=\"/output\""]

Relevant output:

Error: Unable to locate Config file. Perhaps you need to create a new site.
       Run `hugo help new` for details. (Config File "config" Not Found in "[/]")  <-- Parameter had no effect

Command and environment from container (stdout from run.sh)

HOME='/root'
HOSTNAME='cd6df15c5028'
IFS='   
'
OPTIND='1'
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PPID='1'
PS1='\w \$ '
PS2='> '
PS4='+ '
PWD='/'
SHLVL='2'

PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh -c /usr/bin/run.sh server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"
    7 root       0:00 ash /usr/bin/run.sh
    8 root       0:00 ps faux
jtlz2
  • 7,700
  • 9
  • 64
  • 114
draoth
  • 61
  • 4

0 Answers0