In Dockerfile, we can specify the CMD to be in one of three different forms:
...
CMD ["executable","param1","param2"](exec form, this is the preferred form)CMD ["param1","param2"](as default parameters to ENTRYPOINT)CMD command param1 param2(shell form)...
If you use the shell form of the
CMD, then the<command>will execute in/bin/sh -c:FROM ubuntu CMD echo "This is a test." | wc -If you want to run your
<command>without a shell then you must express the command as a JSON array and give the full path to the executable. This array form is the preferred format ofCMD. Any additional parameters must be individually expressed as strings in the array:FROM ubuntu CMD ["/usr/bin/wc","--help"]Source
In docker-compose, we can also use two different forms for its command:
...
Override the default command.
command: bundle exec thin -p 3000The command can also be a list, in a manner similar to dockerfile:
command: ["bundle", "exec", "thin", "-p", "3000"]Source
Do these two different forms in docker-compose behave the same way as the exec and shell forms in Dockerfile do?
No they do not. docker-compose's command always uses the equivalent of Dockerfile's exec form. This can be easily seen with a quick demo:
Dockerfile with shell form processes shell symbols:
FROM alpine:3.11.5
CMD echo foo && echo bar
$ docker run example
foo
bar
Dockerfile with exec form doesn't do any shell processing:
FROM alpine:3.11.5
CMD ["echo", "foo", "&&", "echo", "bar"]
$ docker run example
foo && echo bar
docker-compose's first command form doesn't do any shell processing:
version: "3.7"
services:
example:
image: alpine:3.11.5
command: echo foo && echo bar
$ docker-compose up
Starting example_example_1 ... done
Attaching to example_example_1
example_1 | foo && echo bar
example_example_1 exited with code 0
And neither does docker-compose's second command form:
version: "3.7"
services:
example:
image: alpine:3.11.5
command: ["echo", "foo", "&&", "echo", "bar"]
$ docker-compose up
Starting example_example_1 ... done
Attaching to example_example_1
example_1 | foo && echo bar
example_example_1 exited with code 0
So, if one does want shell processing in docker-compose's command, it has to be explicitly enabled by passing the command to sh -c:
version: "3.7"
services:
example:
image: alpine:3.11.5
command: sh -c "echo foo && echo bar"
$ docker-compose up
Starting example_example_1 ... done
Attaching to example_example_1
example_1 | foo
example_1 | bar
example_example_1 exited with code 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With