43

I have three services to build, A、B and C. A should be built in the very first place, because B and C depend on A (they import A as image). I thought they should be built in order but I just find out they are built in some random order?

So, how do I control build order in docker-compose.yml?

3
  • Looking for some added clarity, are you talking about docker-compose build to build images or are you talking about docker-compose up -d to build/run containers? Commented Nov 8, 2018 at 18:47
  • Not certain it changes much, but I may ask a different question/reference this one, or propose to add/edit some wording and either add a bounty or do some digging on my own depending on which is being referenced. Commented Nov 8, 2018 at 18:51
  • Please check this solution. It works for me Commented Jan 10, 2019 at 4:06

6 Answers 6

22

The accepted answer above does not seem correct.

As seen in the documentation

There are several things to be aware of when using depends_on:

depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started. If you need to wait for a service to be ready, see Controlling startup order for more on this problem and strategies for solving it.

Version 3 no longer supports the condition form of depends_on.

The depends_on option is ignored when deploying a stack in swarm mode with a version 3 Compose file.

Sign up to request clarification or add additional context in comments.

8 Comments

Did you test it;) Actually, depends_on affects the build stage, I tested this just now.
I think this answer actually makes sense in part, I have encountered a problem that stems from this particular piece of docs - one of my containers can be built only after the other one is running. This is what is meant by "depends_on does not wait for db and redis to be “ready” before starting web". However, disagreeing with the accepted answer is incorrect. OP asked about controlling build order and nothing more, whereas this comment talks about container run order.
more specifically it's about not being able to sync what happens after both once containers have started
@maxkoryukov according to docker-compose using depends_on within the context of docker-compose build not an intended use. I agree, it appears to affect the build stage, but it's not a guarantee.
@ArthurWeborg there are enough changes in the Docker and Docker Compose (since I wrote the first comment) and the latest versions support the multistage build. This feature solved a lot of problems; at least, I stopped to use depends_on for building custom images from the same base image.
|
15

Update: In recent practice, I have found my answer to only pertain to run ordering.
Refer to the answer by Quinten Scheppermans and the comment by Authur Weborg about dobi.

You can control build order using depends_on directive.

services:
  ...

  B:
    depends_on:
      - A
  C:
    depends_on:
      - A

9 Comments

Does depends_on have effect on building phase? I had a peek on documents and it seems only have effect on starting phase.
Yes it does. Not sure why it isn't documented
I reached out to docker-compose on github. Their response was that depends_on is not an intended use with docker-compose build
Thanks for letting me know that. I didn't about know dobi. There was the behavior of ordered builds for services based on the service dependency if I remember correctly; as you point out this has changed and only pertains to ordered runs. I'll edit the answer to reference your comment.
In most cases, the multistage build is more appropriate.
|
9

Since compose v2, BuildKit is enabled by default, it will build images parallelly.

By disabling BuildKit you get to build images according to the order in your docker-compose.yml file.

DOCKER_BUILDKIT=0 docker-compose build

If you still want to build images parallelly, you can consider defining services in multiple docker-compose.yml files for building, then composing up in another docker-compose.yml file for deployment.

Comments

3

If you need to run one service before an other you can use docker-compose run bar after setting depends_on: - foo in your docker-compose.yml file.

For example:

# docker-compose.yml

  services:
    foo:
        . . . 
    bar:
         . . . 
      depends_on:
        - foo

then run,

# terminal

user@Name Docker % docker-compose run bar

However, per the docs, this will only control the order in which processes start, not the order in which they finish. This can often lead to situations in which dependent services do not properly start. Potential solutions for this include using wait-for-it, wait-for, or Dockerise. I recommend reading the docs before implementing any of the solutions listed above, as there are caveats.

Comments

3

One thing that fixed a similar issue for me was the additional_contexts option added in version 2.17 of the Compose tool. So if derived/dockerfile has, for example,

COPY --from base-image /build/. /build/.

we can ensure that base-image is built first with a docker-compose that looks like this:

services:
    base:
        build:
            dockerfile: "base/dockerfile"
            context: .
        image: base-image
    derived:
        build:
            dockerfile: "derived/dockerfile"
            context: .
            additional_contexts:
                base-image: service:base

Comments

1

As stated in https://github.com/docker/compose/blob/e9220f45df07c1f884d5d496507778d2cd4a1687/compose/project.py#L182-L183

Preserves the original order of self.services where possible, reordering as needed to resolve dependencies.

So for me it worked by manually sorting the services with the depending services at first and following the services which is used by the other and the other as last.

Example

version: '3'
services:
    mydb:
        image: mydb
    serviceA:
        build: 
            dockerfile: DockerfileA
        depends_on:
            - mydb
    serviceB:
        build:
            dockerfile: DockerfileB # which contains 'FROM serviceA'
        depends_on:
            - mydb

Source: https://github.com/docker/compose/issues/5228#issuecomment-565469948

1 Comment

This doesn't work anymore since builds are run in parallel

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.