# Your Application
  order-service:
    build: .
    ports:
      - "8080:8080"
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/ecommerce
    depends_on:
      - postgres
 
  # Your Database
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: ecommerce
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password

While docker run is for launching a single, specific container via the command line, docker compose up reads your instructions from a docker-compose.yml file and creates, starts, and connects all the containers defined in that file at once.

down

That explains it perfectly! When you run docker compose down, you are telling Docker to stop the containers and then immediately remove them from the system.

Because the containers are removed, they no longer exist in the Docker engine’s “container registry,” which is why docker ps -a comes back empty.

Understanding the Difference in Cleanup

To keep your containers available for inspection after you are done with them, you have a few options depending on what you want to achieve:

  • docker compose down: Stops and removes containers (and usually the networks created for them). Use this when you want a clean slate.

  • docker compose stop: Stops the containers but keeps them in the system. They will show up as “Exited” in docker ps -a.

  • docker compose up -d: Starts them in the background (detached).


To help you master these tasks, here are the steps for managing containers using both the manual CLI approach (docker) and the automated orchestration approach (docker compose).

1. Manual Lifecycle (docker commands)

This approach is best for learning how individual containers behave or for running one-off tasks.

  • Step 1: Create – Use docker create [image_name] to initialize the container without starting it.

  • Step 2: Start – Use docker start [container_id] to move it from “Created” to “Running.”

    • Alternative: Use docker run [image_name] to do both steps at once.
  • Step 3: Pause/Unpause – Use docker pause [container_id] to freeze processes without stopping the container.

  • Step 4: Stop – Use docker stop [container_id] to gracefully shut down the main process (status becomes “Exited”).

  • Step 5: Remove – Use docker rm [container_id] to delete the container entirely.

2. Orchestrated Lifecycle (docker compose commands)

This approach is best for projects where you need multiple services (e.g., a web server and a database) to work together.

  • Step 1: Define – Create a docker-compose.yml file in your directory specifying your services.

  • Step 2: Start Up – Run docker compose up -d in the same directory. This creates, starts, and detaches the containers in the background.

  • Step 3: Monitor/Verify – Use docker compose ps to see the current status of the services defined in your YAML file.

  • Step 4: Stop/Pause – Use docker compose stop to freeze the containers while keeping them on your system.

  • Step 5: Clean Up – Use docker compose down to stop and remove the containers, networks, and (optionally) volumes.