Contents

Docker Compose Up Tutorial: Options and Examples

docker compose up creates and starts the services in compose.yaml. Get started with Docker Compose; see Docker Compose commands for other commands.

Syntax

docker compose up [OPTIONS] [SERVICE...]

If you don't specify a service, Compose runs them all. up proceeds in this order: create networks, create volumes, pull or build images as needed, create containers (recreating those whose configuration changed), and start containers.

Options

OptionDescription
-d, --detachRun in the background. Without this option, logs appear in the foreground; press Ctrl+C to stop
--buildBuild images before starting
--no-buildDon't build; fail if an image doesn't exist
--pull always|missing|neverWhether to pull images before starting
--waitWait until all services are running (and healthy if they have a health check) before returning; implies -d
--wait-timeout SECONDSMaximum wait time with --wait
--force-recreateRecreate containers even if their configuration hasn't changed
--no-recreateDon't recreate containers that already exist
--no-depsDon't start services listed in depends_on
--scale SERVICE=NUMBERStart multiple replicas
--remove-orphansRemove containers for services no longer defined in compose.yaml
-V, --renew-anon-volumesRecreate anonymous volumes instead of reusing those from old containers
--abort-on-container-exitStop all containers when any container stops (can't be used with -d)
--exit-code-from SERVICEUse that service's exit code as the command's exit code; implies the previous option
-t, --timeout SECONDSSeconds to wait when stopping containers
-w, --watchWatch for file changes and sync or rebuild (see Node.js app)
--no-startCreate without starting
--quiet-pull / --quiet-buildHide pull/build progress
--no-log-prefix, --timestamps, --no-colorControl foreground log formatting
--dry-runShow what would happen without running it

Example project

services:
  web:
    image: nginx:1.30-alpine
    ports:
      - "8080:80"
    depends_on:
      - cache
  cache:
    image: redis:8-alpine
    volumes:
      - cache_data:/data
  worker:
    image: alpine:3.23
    command: ["sh", "-c", "echo worker done"]

volumes:
  cache_data:

Start all services

$ docker compose up -d
[+] up 15/15
 ✔ Image redis:8-alpine           Pulled                                                                                                          3.4s
 ✔ Network ref-compose_default    Created                                                                                                         0.0s
 ✔ Volume ref-compose_cache_data  Created                                                                                                         0.0s
 ✔ Container ref-compose-worker-1 Started                                                                                                         0.4s
 ✔ Container ref-compose-cache-1  Started                                                                                                         0.6s
 ✔ Container ref-compose-web-1    Started                                                                                                         0.8s

$ docker compose ps -a
NAME                   IMAGE               COMMAND                  SERVICE   CREATED        STATUS                              PORTS
ref-compose-cache-1    redis:8-alpine      "docker-entrypoint.s…"   cache     1 second ago   Up Less than a second               6379/tcp
ref-compose-web-1      nginx:1.30-alpine   "/docker-entrypoint.…"   web       1 second ago   Up Less than a second               0.0.0.0:8080->80/tcp, [::]:8080->80/tcp
ref-compose-worker-1   alpine:3.23         "sh -c 'echo worker …"   worker    1 second ago   Exited (0) Less than a second ago

worker exits after running echo, so its status is Exited (0). This is normal for a one-off service.

Handle selected services

$ docker compose up -d --no-deps web
[+] up 1/1
 ✔ Container ref-compose-web-1 Running                                                                                                            0.0s

$ docker compose up -d --force-recreate web
[+] up 2/2
 ✔ Container ref-compose-cache-1 Running                                                                                                          0.0s
 ✔ Container ref-compose-web-1   Started                                                                                                          0.4s

$ docker compose up -d --wait cache
[+] up 1/1
 ✔ Container ref-compose-cache-1 Healthy                                                                                                          0.5s
  • --no-deps web: Handle only web, regardless of its dependency on cache. Its configuration hasn't changed, so the output only shows Running.
  • --force-recreate web: Recreate web even if its configuration hasn't changed (Started). Since you didn't add --no-deps, Compose also checks cache, listed in depends_on (Running).
  • --wait cache: Wait until cache is ready before returning. The Redis image doesn't define a health check, so a running container counts as ready.

--scale: multiple replicas

$ docker compose up -d --scale worker=3 worker
[+] up 3/3
 ✔ Container ref-compose-worker-3 Started                                                                                                         0.5s
 ✔ Container ref-compose-worker-2 Started                                                                                                         0.3s
 ✔ Container ref-compose-worker-1 Started                                                                                                         0.2s

$ docker compose ps -a worker
NAME                   IMAGE         COMMAND                  SERVICE   CREATED         STATUS                              PORTS
ref-compose-worker-1   alpine:3.23   "sh -c 'echo worker …"   worker    4 seconds ago   Exited (0) Less than a second ago   
ref-compose-worker-2   alpine:3.23   "sh -c 'echo worker …"   worker    1 second ago    Exited (0) Less than a second ago   
ref-compose-worker-3   alpine:3.23   "sh -c 'echo worker …"   worker    1 second ago    Exited (0) Less than a second ago

--scale worker=3 gives worker three containers, automatically numbered -1, -2, and -3. You can't directly scale a service that maps a host port (ports), because the host ports would conflict.

--exit-code-from: run tests in CI

$ docker compose up --abort-on-container-exit --exit-code-from worker worker
[+] up 2/2
 ✔ Container ref-compose-worker-2 Removed                                                                                                         0.0s
 ✔ Container ref-compose-worker-3 Removed                                                                                                         0.0s
Attaching to worker-1
worker-1  | worker done
worker-1 exited with code 0
Aborting on container exit...
Container ref-compose-worker-1 Stopping
Container ref-compose-worker-1 Stopped
w Enable Watch   d Detach
  • Run only worker. When it exits, --abort-on-container-exit stops the entire up command, and --exit-code-from makes up return worker's exit code. In CI, use this to run a test service: a failed test makes the command fail, which makes CI fail.
  • The worker-2 and worker-3 containers created by the previous --scale command are removed (Removed) this time. Since you didn't specify a replica count, Compose returns to the default of one.

Exercises

Exercise: Edit the example compose.yaml, change the web port to 8081:80, apply the change with one command, and confirm that only web is recreated.

Answer
docker compose up -d

In the output, web shows Recreated/Started and cache shows Running (unchanged). In docker compose ps, the PORTS value for web becomes 0.0.0.0:8081->80/tcp.

FAQ

How do I apply changes to compose.yaml?

Run docker compose up -d again. Compose compares the configuration and recreates only changed services. docker compose restart does not apply new configuration. See [Docker Compose commands](/docker/compose-commands/).

Why doesn't up -d rebuild after I change the Dockerfile?

If an image already exists, up does not rebuild it automatically. Add --build: docker compose up -d --build.

What's the difference between --wait and depends_on with service_healthy?

depends_on controls the startup order between services. --wait makes docker compose up itself wait until all services are running (and healthy if they have a health check) before returning, which is useful when a script or CI job needs to run the next step.

Updated October 14, 2026