Files
docker-docs/compose/startup-order.md
Misty Stanley-Jones a4f5e30249 Various copyedits to reduce future tense, wordiness, and use of 'please' (#5788)
* Reword lots of instances of 'will'

* Reword lots of instances of won't

* Reword lots of instances of we'll

* Eradicate you'll

* Eradicate 'be able to' type of phrases

* Eradicate 'unable to' type of phrases

* Eradicate 'has / have to' type of phrases

* Eradicate 'note that' type of phrases

* Eradicate 'in order to' type of phrases

* Redirect to official Chef and Puppet docs

* Eradicate gratuitous 'please'

* Reduce use of e.g.

* Reduce use of i.e.

* Reduce use of N.B.

* Get rid of 'sexagesimal' and correct some errors
2018-01-25 17:37:23 -08:00

3.3 KiB

description, keywords, title, notoc
description keywords title notoc
How to control service startup order in Docker Compose documentation, docs, docker, compose, startup, order Control startup order in Compose true

You can control the order of service startup with the depends_on option. Compose always starts containers in dependency order, where dependencies are determined by depends_on, links, volumes_from, and network_mode: "service:...".

However, Compose does not wait until a container is "ready" (whatever that means for your particular application) - only until it's running. There's a good reason for this.

The problem of waiting for a database (for example) to be ready is really just a subset of a much larger problem of distributed systems. In production, your database could become unavailable or move hosts at any time. Your application needs to be resilient to these types of failures.

To handle this, design your application to attempt to re-establish a connection to the database after a failure. If the application retries the connection, it can eventually connect to the database.

The best solution is to perform this check in your application code, both at startup and whenever a connection is lost for any reason. However, if you don't need this level of resilience, you can work around the problem with a wrapper script:

  • Use a tool such as wait-for-it, dockerize, or sh-compatible wait-for. These are small wrapper scripts which you can include in your application's image to poll a given host and port until it's accepting TCP connections.

    For example, to use wait-for-it.sh or wait-for to wrap your service's command:

    version: "2"
    services:
      web:
        build: .
        ports:
          - "80:8000"
        depends_on:
          - "db"
        command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
      db:
        image: postgres
    

    Tip

    : There are limitations to this first solution. For example, it doesn't verify when a specific service is really ready. If you add more arguments to the command, use the bash shift command with a loop, as shown in the next example.

  • Alternatively, write your own wrapper script to perform a more application-specific health check. For example, you might want to wait until Postgres is definitely ready to accept commands:

    #!/bin/bash
    # wait-for-postgres.sh
    
    set -e
    
    host="$1"
    shift
    cmd="$@"
    
    until psql -h "$host" -U "postgres" -c '\q'; do
      >&2 echo "Postgres is unavailable - sleeping"
      sleep 1
    done
    
    >&2 echo "Postgres is up - executing command"
    exec $cmd
    

    You can use this as a wrapper script as in the previous example, by setting:

    command: ["./wait-for-postgres.sh", "db", "python", "app.py"]
    

Compose documentation