What's the difference between docker compose up and docker compose up -d?

5 minbeginnerdocker-composedetached-mode

Quick Answer

docker compose up runs in the foreground, attaching your terminal to every service's combined log output — useful for actively watching logs during development, but it blocks your terminal until you stop it (Ctrl+C, which also stops all the services). docker compose up -d (detached mode) starts everything in the background and immediately returns control of your terminal, which is the standard choice for anything beyond active, hands-on local development where you want to keep watching logs directly.

Detailed Answer

Foreground mode — attached, blocking

docker compose up
# api-1  | Server listening on port 3000
# db-1   | database system is ready to accept connections
# web-1  | nginx started
# ... (combined, live, color-coded log output from every service, streamed to your terminal)

Your terminal is now attached to the combined output of every running service. This is genuinely useful when actively developing and you want to watch logs from all services simultaneously in one place, with each line prefixed by which service produced it. Until you press Ctrl+C, this terminal is blocked entirely — you cannot run other commands in that same session while docker compose up is running, unless you open a separate terminal. Pressing Ctrl+C sends a stop signal to every service and then returns control of your terminal.

Detached mode — backgrounded, returns immediately

docker compose up -d
# [+] Running 3/3
#  ✔ Container myapp-db-1   Started
#  ✔ Container myapp-api-1  Started
#  ✔ Container myapp-web-1  Started

Starts every service in the background and immediately hands your terminal back — you can continue running other commands in the same session. To view logs afterward, you explicitly ask for them:

docker compose logs -f       # follow combined logs from all services, on demand
docker compose logs -f api    # follow logs from just the "api" service

Why -d is the standard choice for most real usage

For anything beyond a brief moment of active, hands-on local development where you specifically want to watch logs stream by, -d is almost always what you want. It lets your terminal remain free for other work, and it matches how you would run things in CI, staging, or any semi-automated context. You are not going to leave a terminal session permanently attached and blocked in a CI pipeline or on a server. Combined with docker compose logs -f whenever you do actually want to look at output, detached mode gives you the same log visibility on demand, without the terminal-blocking downside of foreground mode.

Bringing things back down

docker compose down          # stops and REMOVES containers, default network (but NOT named volumes)
docker compose down -v        # also removes named volumes -- be careful, this deletes data!
docker compose stop            # just stops containers, without removing them at all

Regardless of whether you started with foreground or detached mode, docker compose down is the standard teardown command. It is worth explicitly noting that plain docker compose down does not delete named volumes by default, so your data survives. docker compose down -v does delete them, and this distinction matters enormously in practice. An accidental -v on a production-adjacent environment can mean genuine, irreversible data loss.