I am trying to automate a setup where a Docker container starts, updates some local packages, and then immediately launches a Python script. Currently, I can only get one command to run at a time. Is there a way to string multiple commands together in a single docker run or docker exec statement without creating a custom shell script every time? I'm specifically looking for the correct syntax for the shell operators.
3 answers
To run multiple commands in a single Docker execution, you should wrap your commands in a shell call using the -c flag. The syntax looks like this: docker run image_name sh -c "command1 && command2". Using the && operator ensures that the second command only runs if the first one succeeds. If you want both to run regardless of the outcome, use a semicolon ; instead. This is incredibly useful for ephemeral containers where you need to perform a quick update and then execute a binary. In a production Cloud Technology environment, this prevents the overhead of maintaining dozens of small, slightly different Dockerfiles for one-off tasks.
Does this same logic apply when I am using docker exec on an already running container? I tried running a complex pipe command last week and it seemed to execute on my host machine instead of inside the container.
For very complex strings, I find it easier to use the heredoc syntax in a bash script, but for 2-3 commands, the sh -c method is definitely the fastest way to get things done.
I agree, Nancy. The sh -c approach is the bread and butter of Docker automation. It’s a simple trick that separates the beginners from the advanced users in cloud orchestration.
That happened because the host shell interpreted the command before Docker could! To fix this, you must wrap the entire string in quotes after the sh -c part, just like Barbara mentioned. For example: docker exec my_container sh -c "ls && echo done". This forces the entire string to be passed into the container's environment first, ensuring the shell operators are executed internally rather than on your local terminal.