Background
On a recent project, I needed to run a Docker Compose network.
However, I needed one of the containers to wait and not start
until the other containers were up-and-running.
The Problem
In this example, I need a utils
container to run after participant1
and participant2
are up-and-running. Otherwise, the result is one of these errors, depending on the race conditions:
Node participant1 is not initialized and
therefore does not have an Id assigned yet.
java.lang.IndexOutOfBoundsException:
1 is out of bounds (min 0, max 0)
The Solution
- Turn on the gRPC Health Service on the Canton nodes. For example:
canton {
participants {
participant1 {
:
:
monitoring.grpc-health-server {
address = participant1
port = 5861
}
}
}
}
- Add a Docker Compose
healthcheck
for the containers. For example:
services:
participant1:
:
:
healthcheck:
test:
[
"CMD",
"/usr/local/bin/grpc_health_probe",
"--addr",
"participant1:5861"
]
- Add a Docker Compose
condition
to the dependent container. For example:
services:
utils:
:
:
depends_on:
participant1:
condition: service_healthy
participant2:
condition: service_healthy
Sample Outputs
Before
> docker compose up
[+] Running 5/5
✔ Network daml-public-demos_default Created
✔ Container mydomain Created
✔ Container participant2 Created
✔ Container participant1 Created
✔ Container utils Created
Attaching to utils
utils | ERROR Node participant1 is not initialized
and therefore does not have an Id assigned yet.
After
> docker compose up
[+] Running 5/4
✔ Network daml-public-demos_default Created
✔ Container mydomain Created
✔ Container participant2 Created
✔ Container participant1 Created
✔ Container utils Created
Attaching to utils
utils | alice::12202df...
utils | bob::12209f3...
Source Code
The demo source code is available here.