3.2 · Driving the stack: up, down, logs, ps

Level 3 · Docker Compose

3.2Driving the stack: up, down, logs, ps

Goal: start, monitor and stop a Compose stack without mistakes.
Estimated time: 11 min · self-paced reading · If you only have 5 min: read “The essentials in 30s” + the diagram.

The essentials in 30 seconds

  • up -d creates everything: networks and volumes, image build/pull, startup in order — --build forces a rebuild after a code change.
  • Observe per service, compose-prefixed: compose ps lists the stack, logs -f bdd follows one service, exec web sh goes inside it — never the global docker ps that mixes everything.
  • down keeps, -v destroys: down stops and removes containers + network while keeping volumes; down -v also wipes volumes — deliberate reset only.

Running mini-case — Idir and one down too many

Idir, junior DevOps in Algiers, "cleans" his machine with a docker compose down -v before a demo — and wipes the test database filled the day before by his colleague. He adopts the safe cycle: up -d, compose ps, logs -f bdd, exec web sh, down WITHOUT -v by default. On the second up, the database is intact: he has understood that down alone is a safe stop, and that -v is a reset you decide, never a cleanup.

This same case returns in the lesson, the diagram, the script and the 48h challenge.

1. up: build and start, observe: ps, logs, exec

docker compose up -d creates networks and volumes, downloads or builds images, then starts services in order — in the background (-d). Without -d, logs attach to the terminal: handy in development to watch the stack being born, blocking as a service. After a code change, --build forces a rebuild: without it, Compose reuses the existing image and your new code is not picked up.

To SEE: docker compose ps lists the containers OF the project, logs -f bdd follows one service's logs live (with no name, the whole stack, each line prefixed), exec web sh goes inside a container. Golden rule: always prefix with compose — docker ps mixes every project on the machine and makes you diagnose the wrong container.

2. down: safe stop by default, reset by decision

docker compose down stops and removes containers + network, but KEEPS volumes: your data survives, the second up finds it again. This is the safe stop, the everyday one. down -v ALSO wipes volumes: a deliberate reset to start from scratch (test database to reinitialise), reserved for a throwaway or acknowledged stack.

When in doubt: without -v. The classic disaster — down -v "to clean up" before a demo — is avoided with this default. Idir made himself a tattooed rule: down alone to stop, -v only when he can name what he accepts losing. The up → observe → down (without -v) cycle is safe by design.

Common misinterpretation: "down -v is the standard cleanup, and docker ps is enough to see my stack". Wrong, twice. down -v DESTROYS the project's volumes: it is not a cleanup, it is a reset — the standard cleanup is down alone. And docker ps shows the WHOLE machine: to see YOUR stack, use compose ps. Project scope on one side, preserved volumes on the other.
The safe stack cycle Start, observe, stop without losing up -d (--build if code changed) Createseverything, starts in backgroundps / logs -f / exec Observe perservice, compose-prefixeddown without -v Containers +network removed, data keptSecond up intact -v onlyfor a decided reset
Start, observe, stop without losing
Text version of the diagram (SEO / screen readers / translation): 1) Start: Idir runs up -d (--build after each code change) instead of attaching logs in production. 2) Observe: compose ps for the project scope, logs -f bdd for the database, exec to enter the web. 3) Stop: down without -v — containers and network removed, volumes kept, second up intact. Lesson: up creates, compose observes, down alone preserves.

One cleanup too many

"Idir ran a down -v 'to clean up' before the demo — the test database filled by his colleague vanished with it."
Since then, -v only on the stack named bac

Cleaning up is down alone; -v is moving out.

🔎 Concrete example — Full cycle: the database survives the restart

Idir runs the safe cycle on his web + database stack.

docker compose up -d
docker compose ps
docker compose logs -f bdd
docker compose exec web sh
docker compose down
docker compose up -d   # les données sont là
# Reset VOLONTAIRE sur stack jetable uniquement :
# docker compose down -v

Reading: the second up finds the database intact — down alone preserves.

Lesson: down without -v = safe stop; with -v = decided reset, never a cleanup.

Section vocabulary

up
Create and start the whole stack: networks, volumes, images (build/pull), containers in order — -d for background.

Simple example: Idir's up -d every morning on the mock-up.

What it is not: starting each container by hand in the right order.

Reflex: --build after each code change.

down
Stop and remove containers + network while KEEPING volumes: the safe everyday stop.

Simple example: Idir's evening down, database intact the next day.

What it is not: a stop that wipes the database.

Reflex: down alone by default, always.

down -v
down + deletion of VOLUMES: deliberate reset to start from scratch, never a cleanup.

Simple example: The acknowledged reset of a throwaway test database.

What it is not: a "cleanup" before a demo with real data.

Reflex: name what you accept losing before any -v.

ps (compose)
List the containers OF the project only — the right scope for diagnosis.

Simple example: compose ps shows Idir's stack, nothing else.

What it is not: global docker ps mixing all projects.

Reflex: always prefix with compose.

logs -f / exec
Follow one service's logs live (logs -f bdd) and enter a container (exec web sh).

Simple example: Idir follows the database at startup then inspects the web.

What it is not: guessing the failure without reading logs.

Reflex: ps spots, logs accuses, exec checks.

In practice — Master the cycle without risking data

  1. Start your stack with -d and list it with compose ps (compare with global docker ps).
  2. Follow the database logs (logs -f bdd) and enter the web (exec web sh).
  3. Stop with down, restart: check that the data survived.
  4. Try down -v on a THROWAWAY stack only, and observe the loss — once is enough.
You drive a full stack (start, observe, stop) without ever risking useful data.

Ready-to-say script — explaining the cycle to a newcomer (30 s)

"up -d to start, compose ps and logs to observe your stack — never the global ps. And to stop: down alone, the data survives. The -v is a reset that wipes volumes: only on throwaway, never to clean up."

Say during onboarding; run the cycle once together.

Copy-paste template — throwaway training stack

# Stack JETABLE : pour vous entraîner (down -v) sans risque.
services:
  web:
    image: nginx:1.27
    ports:
      - "8080:80"
    networks:
      - bacnet
  bdd:
    image: postgres:16.4
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - bacdata:/var/lib/postgresql/data
    networks:
      - bacnet

volumes:
  bacdata:

networks:
  bacnet:

Freelancer

The up → compose ps/logs → down-alone cycle and your demos survive restarts.

SME in Algiers

Idir trains his colleague: down alone in the evening, database intact in the morning.

Project team

Team rule: -v forbidden except on a named throwaway stack (bac, test).

Beginner

This week: one full cycle + one -v reset on throwaway, to feel the difference.

✓ Best practices

  • Always compose + verb (ps, logs, exec) to stay in the project scope.
  • down without -v by default; -d as a service, attached only for debugging.
  • Add --build after each code change, or mount the code with a bind in dev.

✗ Common pitfalls

  • down -v "to clean up": the project's data is wiped.
  • docker ps instead of compose ps: you diagnose the wrong container.
  • Forgetting --build after a code change: the old image is still running.

Key takeaways

  • UP creates everything (-d in background); --build forces a rebuild after a code change.
  • PS / LOGS / EXEC per service, always compose-prefixed (project scope).
  • DOWN keeps volumes (safe stop); -v destroys them (deliberate reset only).
  • The up → observe → down (without -v) cycle is safe by design.

48h challenge — apply tomorrow

Run 1 full cycle on your stack (up -d, ps, logs, exec, down, re-up) and prove the data survives.

Section exit checklist
  • I start in the background and rebuild with --build when code changes.
  • I observe per service in the compose scope.
  • I stop with down alone; -v only on acknowledged throwaway.
Self-rating 1-5: can I name what -v will destroy before typing it?do I systematically prefix with compose?

Frequently asked questions

up does not pick up my new code, why?

Because the image is NOT rebuilt: Compose reuses the existing image by default. Add --build (up -d --build) after each code change, or mount the code with a bind mount in development for direct reload. Check with compose ps that the container has just been recreated.

How to follow several services at once?

Run docker compose logs -f with no service name: the whole stack scrolls, each line prefixed with the service name. Ideal at startup to see the real order and spot who fails. Then zoom in with logs -f bdd on the suspect, then exec to go inside.

Check your understanding

You want to stop the stack while keeping the database. Which command?

Additional resources (optional, to go further)

Level 3 examFresh, harder questions to test what you've learned