docker / docker/compose

Add opt-in ordered replica startup with health-based readiness

Open
#14,232 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

kind/feature
Dominant language
Go
Stars
38.2k
Forks
5.8k
Avg merge
2d 14h
Merged PRs (30d)
55

Description

Description
Description

Docker Compose supports ordering between different services using depends_on and condition: service_healthy.

However, this ordering cannot be applied between replicas of the same service.

For example:

services:
  app:
    image: example/app
    deploy:
      replicas: 3
    healthcheck:
      test: ["CMD", "/app/healthcheck.sh"]
      interval: 5s
      timeout: 3s
      retries: 20

Compose starts all three replicas without waiting for one replica to become healthy before starting the next. Although container start API calls may be issued sequentially, application initialization occurs concurrently.

Desired behavior

I would like an opt-in mode that starts replicas in sequence and waits for each replica to become ready:

app-1 starts
  ↓
app-1 post_start hooks complete
  ↓
app-1 becomes healthy
  ↓
app-2 starts
  ↓
app-2 post_start hooks complete
  ↓
app-2 becomes healthy
  ↓
app-3 starts

This would provide behavior similar to chaining separately declared services:

services:
  app-0:
    image: example/app

  app-1:
    image: example/app
    depends_on:
      app-0:
        condition: service_healthy

  app-2:
    image: example/app
    depends_on:
      app-1:
        condition: service_healthy

That workaround loses the benefits of Compose replicas and requires manually duplicating each service.

Suggested configuration

The exact syntax is open for discussion. One possible configuration is:

services:
  app:
    image: example/app
    deploy:
      replicas: 3
      startup_config:
        order: sequential
        condition: service_healthy
        failure_action: pause

startup_config should be optional. When it is not provided, Docker Compose should preserve its existing replica startup behavior without requiring an explicit order: parallel setting.

This makes ordered, health-gated startup opt-in and maintains backward compatibility with existing Compose files.

Expected semantics

When ordered startup is enabled:

  1. Start the lowest-numbered missing replica.
  2. Run and complete its post_start hooks.
  3. Wait until its healthcheck reports healthy.
  4. Start the next replica.
  5. Stop the sequence if a replica exits, becomes unhealthy, a hook fails, or the readiness timeout is exceeded.
  6. Apply the same behavior during initial up and later scale-up operations.
  7. Leave the current behavior unchanged when the option is omitted.

A service using condition: service_healthy should require a healthcheck. A separate condition could support applications that only need the previous replica to be running.

Use case

This is useful for stateful or clustered applications where each member must register, join the cluster, initialize data, update shared configuration, or elect a leader before another member starts.

In our case, multiple replicas start concurrently and attempt to update the cluster configuration at the same time. Two clients can read the same available port before either client finishes writing its configuration. Both clients are then assigned the same port, resulting in a configuration mismatch error and preventing the cluster from starting correctly.

The expected sequence is:

app-1 starts
  ↓
app-1 updates the cluster configuration
  ↓
app-1 completes its post_start work and becomes healthy
  ↓
app-2 starts and receives the next available port
  ↓
app-2 becomes healthy
  ↓
app-3 starts
Environment
Docker Compose version
Docker Compose version v5.3.1
Docker version
Client: Docker Engine - Community
 Version:           29.6.2
 API version:       1.55
 Go version:        go1.26.5
 Git commit:        dfc4efb
 Built:             Thu Jul 16 16:12:21 2026
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          29.6.2
  API version:      1.55 (minimum version 1.40)
  Go version:       go1.26.5
  Git commit:       3d80467
  Built:            Thu Jul 16 16:12:21 2026
  OS/Arch:           linux/amd64
  Experimental:     false
 containerd:
  Version:          v2.2.6
  GitCommit:        11ce9d5f3c68c941867e82890e93e815c1304f1b
 runc:
  Version:          1.3.6
  GitCommit:        v1.3.6-0-g491b69ba
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
Related issues
  • #5422 — staggered container startup
  • #8849 — limiting startup parallelism
  • #14081 — start-phase plan engine and replica chains

Those discussions concern request ordering, startup parallelism, or internal planning. This request specifically adds a readiness barrier between replicas.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing related issues #5422, #8849, and #14081, then trace the existing replica startup and scale-up behavior in Docker Compose. Define the opt-in configuration and readiness semantics, including healthchecks, hooks, failures, and backward compatibility; done means ordered initial startup and scale-up work without changing omitted-option behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, docker-compose
Domain
devops, infrastructure
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.