Docker Compose: How to Execute Multiple Commands in a Service

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 or bash -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

MethodBest Use Case
sh -c "cmd1 && cmd2"Simple one-liners
Shell script (start.sh)Multiple steps or better readability
entrypoint: overrideReplace container’s default startup
Sharing Is Caring:

Leave a Comment