miku
miku

Reputation: 188064

docker-compose wait on other service before build

There are a few approaches to fix container startup order in docker-compose, e.g.

However, if one of the services in a docker-compose file includes a build directive, it seems docker-compose will try to build the image first (ignoring depends_on basically - or interpreting depends_on as start dependency, not build dependency).

Is it possible for a build directive to specify that it needs another service to be up, before starting the build process?

Minimal Example:

version: "3.5"
services:
  web:
    build: # this will run before postgres is up
      context: .
      dockerfile: Dockerfile.setup # needs postgres to be up
    depends_on:
      - postgres
    ...
  postgres:
    image: postgres:10
    ...

Notwithstanding the general advice that programs should be written in a way that handles the unavailability of services (at least for some time) gracefully, are there any ways to allow builds to start only when other containers are up?


Some other related questions:


Update/Solution: Solved the underlying problem by pushing all the (database) setup required to the CMD directive of a bootstrap container:

FROM undertest-base:latest

...

CMD ./wait && ./bootstrap.sh

where wait waits for postgres and bootstrap.sh contains the code for setting up the postgres database with fixtures so the over system becomes fully testable after that script.

With that, setting up an ephemeral test environment with database setup becomes a simple docker-compose up again.

Upvotes: 2

Views: 1620

Answers (1)

David Maze
David Maze

Reputation: 159030

There is no option for this in Compose, and also it won't really work.

The output of an image build is a self-contained immutable image. You can do things like docker push an image to a registry, and Docker's layer cache will avoid rebuilding an image that it's already built. So in this hypothetical setup, if you could access the database in a Dockerfile, but you ran

docker-compose build
docker-compose down -v
docker-compose up -d --build

the down -v step will remove the storage the database uses. While the up --build option will cause the image to be rebuilt, the build sequence will skip all of the steps and produce the same image as originally, and whatever changes you might have made to the database won't have happened.

At a more mechanical layer, the build sequence doesn't use the Compose-provided network, so you also wouldn't be able to connect to the database container.

There are occasional use cases where a dependency in build: would be handy, in particular if you're trying to build a base image that other images in your Compose setup share. But neither the stable Compose file v3 build: block nor the less-widely-supported Compose specification build: supports any notion of an image build depending on anything else.

Upvotes: 2

Related Questions