When defining services in a docker-compose.yml
file, it’s common to need more than one command to run when the container starts. But Docker Compose expects the command:
or entrypoint:
directive to run a single command. So how can you execute multiple commands in sequence?
In this post, we’ll show you how to run multiple commands in Docker Compose the right way, and the common methods to avoid unexpected issues.
🎯 The Problem
If you try this in docker-compose.yml
:
services:
app:
image: node:18
command: npm install && npm start
It won’t work as expected. Why?
Because command:
is interpreted as a single executable and its arguments—not as a shell command with operators like &&
.
✅ Solution 1: Use a Shell to Chain Commands
Wrap your commands inside a shell:
services:
app:
image: node:18
command: /bin/sh -c "npm install && npm start"
Or if your base image uses bash
:
command: bash -c "npm install && npm start"
✅ Explanation:
sh -c
orbash -c
allows you to run a string of commands as if typed into a shell.&&
ensures that the second command runs only if the first succeeds.
✅ Solution 2: Use a Shell Script
For more complex setups, use a script file.
Example:
start.sh
#!/bin/sh
npm install
npm run migrate
npm start
Make sure it’s executable:
chmod +x start.sh
Then use it in docker-compose.yml
:
services:
app:
image: node:18
volumes:
- .:/app
working_dir: /app
command: ./start.sh
✅ Benefits:
- Clean, readable
- Easy to maintain
- Reusable across environments
✅ Solution 3: Use entrypoint:
for Pre-Execution Logic
You can also modify the entrypoint
if you want to override the container’s default startup behavior.
services:
app:
image: python:3.11
entrypoint: /bin/sh -c "pip install -r requirements.txt && python app.py"
However, use entrypoint:
carefully as it replaces the original entrypoint defined in the Dockerfile.
🚫 What Not to Do
Avoid trying this:
command: ["npm install", "npm start"]
This syntax runs npm install
as the entire command, and ignores the second. It doesn’t split or chain commands.
📝 Conclusion
To run multiple commands in Docker Compose:
- Use
sh -c "cmd1 && cmd2"
to run simple chained commands. - Use a
start.sh
script for complex sequences. - Avoid invalid YAML command arrays unless you’re calling a single binary.
With these techniques, you can keep your services clean, reproducible, and production-ready.
🔑 Quick Summary
Method | Best Use Case |
---|---|
sh -c "cmd1 && cmd2" | Simple one-liners |
Shell script (start.sh ) | Multiple steps or better readability |
entrypoint: override | Replace container’s default startup |