I'm building a Windows based docker image:
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
# omitted for brevity
ENTRYPOINT ["c:\spinner.exe", "service", "w3svc", "-t", "c:\iislog\W3SVC\u_extend1.log"]
The base image sets the shell to Powershell
:
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
My understanding was that when the exec form of the ENTRYPOINT
instruction is used, the command will be executed without a shell. However, when I create the container, it fails with this error:
$ docker run -d -p 80:80 --isolation process --name pht site:local
$ docker logs pht
At line:1 char:77
+ ... ference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; [C:\\spin ...
+ ~
Missing ] at end of attribute or type literal.
At line:1 char:78
+ ... '; $ProgressPreference = 'SilentlyContinue'; [C:\\spinner.exe, servic ...
+ ~~~~~~~~~~~~~~
Unexpected token ':\\spinner.exe' in expression or statement.
At line:1 char:92
+ ... ; $ProgressPreference = 'SilentlyContinue'; [C:\\spinner.exe, service ...
+ ~
Missing argument in parameter list.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordEx
ception
+ FullyQualifiedErrorId : EndSquareBracketExpectedAtEndOfAttribute
And when I inspect the stopped container, I see the executed command was through shell:
"Entrypoint": [
"powershell -Command $ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; [\"c:\\spinner.exe\", \"service\", \"w3svc\", \"-t\", \"c:\\iislog\\W3SVC\\u_extend1.log\"]"
],
Am I misunderstanding something here?
The exec syntax requires JSON format, which means that \
instances in the array elements must be escaped as \\
.
Since your ENTRYPOINT
instruction therefore does not contain a valid JSON array, it looks like Docker is falling back to shell syntax and therefore passes your ENTRYPOINT
argument to the shell, which in your case is PowerShell, as defined in your SHELL
instruction - and that results in a broken shell command.[1]
A syntactically correct ENTRYPOINT
in exec format - i.e., valid JSON - prevents involvement of a shell, which is the correct approach in this case, given that your command contains literal elements only.
Therefore, try the following (\
instances escaped as \\
):
ENTRYPOINT ["c:\\spinner.exe", "service", "w3svc", "-t", "c:\\iislog\\W3SVC\\u_extend1.log"]
That way, Docker should end up executing the following command line in the container:
c:\spinner.exe service w3svc -t c:\iislog\W3SVC\u_extend1.log
[1] What happens is that the malformed ENTRYPOINT
argument, ["c:\spinner.exe", "service", "w3svc", "-t", "c:\iislog\W3SVC\u_extend1.log"]
, is taken to be a single argument - a verbatim string to be escaped based on JSON rules (doubling of \
chars.) - to be passed to the shell, as defined by your SHELL
instruction. This means appending that argument to the last argument of your SHELL
array, preceded by a space character. What you saw in the logs is evidence of that.