I'm trying to do two commands in docker exec. Concretely, I have to run a command inside a specific directory. I tried this, butit didn't work:
docker exec [id] -c 'cd /var/www/project && composer install'
Parameter -c
is not detected.
I also tried this:
docker exec [id] cd /var/www/project && composer install
But the command composer install
is executed after the docker exec
command.
How can I do it?
In order to execute multiple commands using the “docker exec” command, execute “docker exec” with the “bash” process and use the “-c” option to read the command as a string. Note : simple quotes may not work in your host terminal, you will have to use double quotes to execute multiple commands.
There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect. If CMD is used to provide default arguments for the ENTRYPOINT instruction, both the CMD and ENTRYPOINT instructions should be specified with the JSON array format.
Docker Run vs Docker Exec! This is a fairly common question – but has a simple answer! In short, docker run is the command you use to create a new container from an image, whilst docker exec lets you run commands on an already running container! Easy!
In your first example, you are giving the -c
flag to docker exec
. That's an easy answer: docker exec
does not have a -c
flag.
In your second example, your shell is parsing this into two commands before Docker even sees it. It is equivalent to this:
if docker exec [id] cd /var/www/project
then
composer install
fi
First, the docker exec
is run, and if it exits 0 (success), composer install
will try to run locally, outside of Docker.
What you need to do is pass both commands in as a single argument to docker exec
using a string. Then they will not be interpreted by a shell until already inside the container.
docker exec [id] "cd /var/www/project && composer install"
However, as you noted in the comments, this also does not work. That's because cd
is a shell builtin, and doesn't exist on its own. Trying to execute it as the initial command will fail. So the next step is to hand this off to a shell to execute.
docker exec [id] "bash -c 'cd /var/www/project && composer install'"
And finally, at this point the &&
has moved into an inner set of quote marks, so we don't really need the quotes around the bash
command... you can drop them if you prefer.
docker exec [id] bash -c 'cd /var/www/project && composer install'
Everything after the container id is the command to run, so in the first example -c
isn't an option to exec, but a command docker tries to run and fails since that command doesn't exist.
Most likely you found this syntax from a docker run
command where the entrypoint was set to /bin/sh
. However, exec bypasses the entrypoint, so you need to include the full command to run. As others have pointed out, that command includes a shell like bash or in the below example, sh:
docker exec [id] /bin/sh -c 'cd /var/www/project && composer install'
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